python之路——第二塊(裝飾器、生成器、叠代器)
裝飾器
def deco(count): def func(num): if num < 10: count(num) else: exit() return func @deco def count(num): a = 0 for i in range(num): a += i print(a) count(11)
註:deco(count)和下面的count(num)中的count只是一個形參,count可以用任何變量名替換,但是num是一定要有,因此傳入的實參是被裝飾函數,被裝飾函數有num形參。
總結:1、裝飾器沒有修改被裝飾函數的源代碼和調用方式
2、用到了高階函數,把被裝飾函數函數名當做實數傳入裝飾器第一級函數;裝飾器第二級函數包含被裝飾函數以及要加的新功能,然後將第二級函數的內存地址返回給第一級函數。這樣就能達到裝飾的效果。
3、用到了嵌套函數,第一級函數嵌套第二級函數。
生成器:一邊循環一邊計算的機制,節省內存空間;只有在調用這個生成器時,才會生成想應的數據。
首先看一個列表生產式
a = [i*2 for i in range(10)] #列表生產式 print(a) #直接打印a列表的所有結果
但是如果range()裏面是10000的時候,就會占用電腦大量內存,我們需要的僅僅是其中一個數據。此時可以用生成器
b = (i*2 for i in range(10)) #生成器 print(b) #打印的是內存地址
此時,b就是生成器,打印b顯示的是內存地址,可用_next_方法
print(b.__next__()) #0 print(b.__next__()) #2 print(b.__next__()) #4
除了這種列表生產器,還可以把函數改裝生成器,比如下面一個斐波那契函數
def fei(max): #斐波那契額函數 a,b,n = 0,1,0 while n < max: print(b) a,b = b,a+b n += 1
調用這個函數,輸出的是整個斐波那契列表,但是可以把print(b)改成yield b的方法,把函數變成生成器。
def feib(max): a,b,n = 0,1,0 while n < max: yield b #將print 改為 yield 變成斐波那契生成器 a,b = b,a+b n += 1 f = feib(10) print(f.__next__()) #1 print(f.__next__()) #1 print(f.__next__()) #2
可以用for的方法,來輸出生產器的所有結果
for i in fei(10): print(i)
輸出的結果和
f = fei(10)
的結果一樣
可叠代對象:可以直接作用於for
循環的對象統稱為可叠代對象:Iterable
叠代器:可以被_next_()
函數調用並不斷返回下一個值的對象稱為叠代器:Iterator
1、可以使用isinstance()
判斷一個對象是否是Iterable
對象
2、集合數據類型,如list
、tuple
、dict
、set
、str
等可以使用for循環,但是不具有_next_()方法,使用只屬於可叠代對象,不屬於叠代器
所以,生成器屬於叠代器,也屬於可叠代對象,但是叠代器不一定是生成器。
python之路——第二塊(裝飾器、生成器、叠代器)