1.生成器:
1.1 起源:
如果列表中有一萬個元素,我們只想要訪問前面幾個元素,對其進行相關操作,通過for循環方式效率太低,並且後面的元素會浪費內存,還會受到內存限制,所以產生生成器來解決這個問題。
1.2 啥是生成器:
通過某種算法推演出我們所需要的內容,而不必創建所有的列表元素。這種一邊循環一遍計算的機制叫做生成器(generator)。通過使用yield返回值函數,每次調用yield都會暫停,將值返回出去進行計算處理。生成器類似於返回值為數組的一個函數,這個函數可以接受參數,可以被調用,但是,不同於一般的函數會一次性返回包括了所有數值的數組,生成器一次只能產生一個值,這樣消耗的內存數量將大大減小。生成器也是一個更加複雜的迭代器。
1.3 創建生成器:
方法一:把列表生成式的 [ ] 改為 ( ) 即可。
generator_item = ( i*i for i in range(10)) 輸出: <generator> at 0x000002A4CBF9EBA0 >/<generator>
如果要一個個打印出來,可以通過next()函數獲得generator的下一個返回值
print(next(generator_item)) ==> 1
print(next(generator_item)) ==> 4
print(next(generator_item)) ==> 9
......
通過這種方式(調用next()方法) ,最後會報錯 StopIteration ,所以一般不用這種方法,一般用for循環遍歷生成器
方法二:通過函數的形式創建,典型例子,斐波那契數列
def fib(max):
n,a,b =0,0,1
while n < max:
yield b
a,b =b,a+b
n = n+1
return 'done'
g = fib(6)
while True:
try:
x = next(g)
print('generator: ',x)
except StopIteration as e:
print("生成器返回值:",e.value)
break
2. 迭代器:(迭代就是循環)
2.1 定義: 迭代器包含有next方法的實現,在正確的範圍內返回期待的數據以及超出範圍後能夠拋出StopIteration的錯誤停止迭代。
2.2 我們已經知道,可以直接作用於for循環的數據類型有以下幾種:
一類是集合數據類型,如list,tuple,dict,set,str等
一類是generator,包括生成器和帶yield的generator function
這些可以直接作用於for 循環的對象統稱為可迭代對象:Iterable
可以使用isinstance()判斷一個對象是否為可 Iterable 對象
生成器不但可以作用於for循環,還可以被next()函數不斷調用並返回下一個值,直到最後拋出StopIteration錯誤表示無法繼續返回下一個值
使用 iter() 函數可以將序列轉化為迭代器
2.3 小結
- 凡是可作用於 for 循環的對象都是 Iterable 類型;
- 凡是可作用於 next() 函數的對象都是 Iterator 類型,它們表示一個惰性計算的序列;
- 集合數據類型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,不過可以通過 iter() 函數獲得一個 Iterator 對象
3. with上下文管理器
一些不得不知道的知識:
上下文管理協議:context mangement protocol。協議,包含了某些方法,大家都應該跟著去做的。在這裡就是 __enter__和__exit__兩個方法。
上下文管理器:支持上下文管理協議的對象,這種對象實現了__enter__和__exit__方法。
as的作用:將返回的對象賦給一個變量,以方便以後的使用。
with是一個對象
運行步驟:
1.當進入語句塊時,先執行__enter__方法,把文件打開,並返回該文件對象
2.執行代碼塊內容
3.離開代碼塊的時候,執行__exit__方法,關閉文件。
在執行過程中,無論遇到什麼異常,都是要離開代碼塊的,這個時候就由__exit__方法接管了。可以在__exit__中定義,讓異常顯示出來。
閱讀更多 編程python新視野 的文章