迭代器
迭代器從表面上看是一個數據流對象或容器,當使用其中的數據時,每次從數據流中取一個數據,直到數據被取完,而且數據不會被重複使用。
自定義迭代器
這個我單獨做成一篇實例博文:
python實現設計迭代器指南(含樣例啓發)
內置迭代器工具
iter()
格式:
iter(iterable)
iter(callable,sentinel)
第一種原型中只有一個參數,要求參數爲可迭代類型,當然也可以使用前文所說的各種序列類型。
第二種原型中具有兩個參數,第一個參數是可調用類型,一般爲函數;第二個參數被稱爲“哨兵”,即當第一個參數(函數)調用返回值等於第二個參數的值時,迭代器會停止迭代
例子:實現一個第二種原型迭代器,迭代出2,4,6
class Counter(object):
def __init__(self, x=0):
self.x = x
counter = Counter()
def used_iter():
counter.x += 2
return counter.x
for i in iter(used_iter, 8):
print(i)
生成器
使用生成器,可以生成一個值的序列用於迭代,並且這個值的序列不是一次生成的,而是使用一個,再生成一個。
生成器創建
例子:實現遞減生成器,並測試是否一次生成完畢
def myYield(n):
while n > 0:
print('開始生成....:')
yield n
print('完成一次...')
n -= 1
if __name__ == '__main__':
my_yield = myYield(3)
print('已經實例化生成器對象')
my_yield.__next__()
print('第二次調用__next__()方法:')
my_yield.__next__()
答案跟定義相同!!!
深入生成器
yield語句不僅可以使函數成爲生成器和返回值,還可以接受調用者傳來的數值。但值得注意的是:第一次調用生成器時不能傳送給生成器None以外的值,否則會引發錯誤。
例子:實現遞減生成器,避免傳入None以外的值
def myYield(n):
while n > 0 :
rcv = yield n
n -= 1
if rcv is not None:
n = rcv
if __name__ == '__main__':
my_yield = myYield(3)
print(my_yield.__next__())
print(my_yield.__next__())
生成器與協程
採用一般的方法來實現生產者與消費者這個傳統的併發與同步程序設計問題,通過生成器實現
例子:生產者模型
def consumer():
print('等待接受處理任務....')
while True:
data = (yield)
print('收到任務:', data)
def producer():
c = consumer()
c.__next__()
for i in range(3):
print('發送一個任務....', '任務%d' % i)
c.send('任務%d' % i)
if __name__ == '__main__':
producer()
裝飾器
裝飾器是一種增加函數或類功能的簡單方法,它可以快速地給不同的函數或類插入相同的功能。
裝飾器概述
要用裝飾器來裝飾對象,必須先定義裝飾器,裝飾器的定義與普通函數的定義在形式上完全一致,只不過裝飾器函數的參數必須有函數或類對象,然後在裝飾器函數中重新定義一個新的函數或類,並在其中執行某些功能前後或中間來使用被裝飾的函數或類,最後返回這個新定義的函數或類。
裝飾函數
用裝飾器裝飾函數,首先要定義裝飾器,然後用定義的裝飾器來裝飾函數
例子:自定義一個裝飾器,使其函數運行開始時有提示,結束時也有提示
def abc(fun):
def wrapper(*args, **kwargs):
print('開始運行...')
fun(*args, **kwargs)
print('運行結束!')
return wrapper
@abc
def demo_decoration(x):
a = []
for i in range(x):
a.append(i)
print(a)
if __name__ == '__main__':
demo_decoration(5)
裝飾類
裝飾器不僅可以裝飾函數,也可以裝飾類。定義裝飾類的裝飾器,採用的方法是:定義內嵌類的函數,並返回新類。
例子:演示一個裝飾類實現打印三個座標值
def abc(myclass): # 定義類裝飾器
class InnerClass: # 定義內嵌類
def __init__(self,z=0):
self.z = 0
self.wrapper = myclass() # 實例化被裝飾類
def position(self):
self.wrapper.position()
print('z axis:', self.z)
return InnerClass
@abc
class coordination(object):
def __init__(self,x=0,y=0):
self.x = x
self.y = y
def position(self):
print('x axis:',self.x)
print('y axis:',self.y)
if __name__ == '__main__':
coor = coordination()
coor.position()
總結
通過迭代器、生成器、裝飾器的學習,python的內化功夫又上升了一個檔次。其中迭代器可以不斷地遍歷,生成器一次生成一個,裝飾器簡化函數操作。都是及其有用的