(一)生成器
通過列表生成式,我們可以直接建立乙個列表。但是,受到記憶體限制,列表容量肯定是有限的。而且,建立乙個包含100萬個元素的列表,不僅占用很大的儲存空間,如果我們僅僅需要訪問前面幾個元素,那後面絕大多數元素占用的空間都白白浪費了。這個其實是惰性求值,資料不是全部一下子載入到記憶體中,而是乙個乙個來。
g = (i for i in range(10))print(g)#把列表推導的圓括號換成方括號就變成了乙個生成器# at 0x000001aa11dd3d68>
我可以通過 next(g) 方法訪問元素,在訪問完所有的元素後會丟擲乙個異常。但是這種使用方法幾乎不被推薦。正確的做法是用 yield 編寫乙個生成器函式,最後返回乙個可迭代物件,然後用 for 迴圈來呼叫。
1 defmy_range(n):2 i =03 while i !=n:4 i += 1
5 yieldi # 協程6
8 r = my_range(10) # 返回乙個可迭代物件9 for i inr:10 print(i)
yield 這種處理方式其實是協程,這個有點像系統終中斷。協程,又稱微執行緒,纖程。英文名coroutine。協程的概念很早就提出來了,但直到最近幾年才在某些語言(如lua)中得到廣泛應用。子程式,或者稱為函式,在所有語言中都是層級呼叫,比如a呼叫b,b在執行過程中又呼叫了c,c執行完畢返回,b執行完畢返回,最後是a執行完畢。所以子程式呼叫是通過棧實現的,乙個執行緒就是執行乙個子程式。子程式呼叫總是乙個入口,一次返回,呼叫順序是明確的。而協程的呼叫和子程式不同。協程看上去也是子程式,但執行過程中,在子程式內部可中斷,然後轉而執行別的子程式,在適當的時候再返回來接著執行。——廖雪峰
(二)重要的魔法方法
__getattribute__ # 可以 hook 住所有的讀操作,在訪問元素的時候 foo.name 先呼叫 __getattribute__
__setattribute__
# 什麼都沒有的時候才會被觸發
# 這個操作更加的重要,下面兩個函式被觸發的時候,一定沒有這個屬性 missing method
__getattr__
__setattr__
class foo(object):
def __init__(self, name):
self.id = none
self.name = name
def __getsttribute__(self, item):
print(item)
foo = foo('jack')
foo.name
# 輸出 jack
# __getattr__
class any(object):
def __getattr__(self, item):
print(item)
def __setattr__(self, k, v):
print("set", k, v)
a = any()
a.a# 輸出 a ,這是乙個沒有的屬性
# __setattr__
a.a = 1
# 輸出 set a 1
希望有乙個類可以接受任何引數和任何函式
(三)裝飾器與閉包
裝飾器是為了給函式或類新增一些特定的功能,如列印日誌等。裝飾器採用閉包原理實現。閉包就是有乙個內層函式,並且外層函式返回內層函式的函式名。外層函式傳入的是乙個函式名或者類名。
使用裝飾器實現乙個單例模式
def singleton(cls, *args, **kwargs):
instance = {}
if cls not in instance:
instance[cls] = cls(*args, **kwargs)
return instance[cls]
@singleton
class foo(object):
pass
foo1 = foo()
foo2 = foo()
print(foo1 is foo2)
# 輸出: true
(四) 運算子過載
# __repr__
# __str__的區別:
兩個方法同時定義的時,呼叫 print 函式列印物件的時候,會優先呼叫 __str__ 方法
__str__是面向使用者的,而__repr__面向程式設計師
重構了 __str__方法,互動式呼叫顯示的式位址,直接 print 的時候是顯示重構的內容。
__repr__ 改了的話,互動式和 print 都是統一的
class com(object):
加減法實現運算子過載
def __init__(self, value):
self.value = value
def __add__(self, other):
return self.value + other
def __sub__(self, other):
return self.value - other
com = com(5)
print(com + 5)
print(com - 10)
索引的取值和複製 __getitem__, __setitem__
通過這兩個方法實現 i[index] 的取值、賦值和切片操作
class index(object):
data = [8,2,5,5,1,5,3,9,6]
def __getitem__(self, index):
return self.data[index]
def __setitem__(self, k, v):
self.data[k] = v
print(self.data)
i = index()
print(i[3])
i[0] = 8999
print(i[1:])
__iter__,__next__ 實現迭代器
什麼是迭代器? 能夠把容器中的元素遍歷(for loop)訪問的物件被稱為迭代器
含有 __iter__() 方法或 __getitem__() 方法的物件稱之為可迭代物件。
Python學習筆記 1 1 2 認識Python
一.課程目標 二.詳情解讀 1.初識pythonpython語言是一種高階程式語言,它於1991年由吉多.範羅蘇姆 guido van rossum 發明。目前主要應用於web開發 gui開發 網路爬蟲 資料科學 人工智慧等領域。python官方 python語言也是一種多正規化程式語言,即物件導向...
python實現演算法 kmp演算法python實現
kmp演算法python實現 kmp演算法 kmp演算法用於字串的模式匹配,也就是找到模式字串在目標字串的第一次出現的位置 比如abababc 那麼bab在其位置1處,bc在其位置5處 我們首先想到的最簡單的辦法就是蠻力的乙個字元乙個字元的匹配,但那樣的時間複雜度會是o m n kmp演算法保證了時...
python呼叫qt Qt 下呼叫 Python
qt是乙個跨平台的c 圖形使用者介面應用程式框架,而python是一門非常強大的程式語言,本文主要介紹了如何在osx系統下qt呼叫python指令碼。先上 include 包含呼叫python相應的標頭檔案 include int main int argc,char ar 初始化python直譯器...