__iter__
方法
只要內部含有__iter__
方法都是可迭代的面試
print(__iter__() in dir([]))
__next__和__iter__
方法都是迭代器.__iter__()
就是一個迭代器迭代器中的__next__()
方法就是一個一個的獲取值app
節省內存空間函數
#模仿for循環獲取列表的元素 l = [1, 2, 3, 4, 5] iterator = l.__iter__() while 1: try: print(iterator.__next__()) except: break
直接給你內存地址線程
只有內部有__iter__()
方法的數據才能用for循環指針
迭代器不能記住本身迭代到哪兒了code
yield
就是生成器函數yield
和return
不能共用yield
只能在函數裏用生成器函數執行以後會產生一個生成器做爲返回值對象
#普通函數 def func(): print(1) return 'a' #調用 ret = func() print(ret) #結果 1 a #生成器函數 def generator(): print(1) yield 'a' #調用 ret = generator() print(ret) #結果 <generator object generator at 0x000000000> #返回的是一個內存地址 #換種方式調用 ret = generator() print(ret.__next__()) #結果 1 a
yield
不會像return
同樣結束函數yield
也會返回一個值每調用一個__next__()
就會輸出一個yield返回的值索引
#定義一個生成器函數 def generator(): for i in range(100): yield i g1 = generator() g2 = generator() #循環打印生成器函數內容 while 1: try: print(g1.__next__()) print(g2.__next__()) except: break #結果是同步運行,因此至關於雙線程
yield
後再也不有函數體了內存
def wrapper(): print(1) yield 8 print(2) yield 8 print(2) #後方沒有yield能夠打印可是報錯
__next__()
和send
效果能夠一致
send()
可以傳值
yield
傳一個值send
使用注意事項
__next__()
調取最後一個yield不能接收外部的值字符串
#send()不傳入參數 def wrapper(): print('=') yield '第一個' print('==') yield '第二個' #調用 g = wrapper() print(g.__next__()) print(g.send(None)) #結果 = 第一個 == 第二個 #send傳入任意參數,如'hello' def wrapper(): print('=') countent = yield '第一個' #這裏給yield賦值countent print('~~', countent) #這裏添加一個打印信息 print('==') yield '第二個' #調用 g = wrapper() print(g.__next__()) #第一個值的調取必須用__next__() print(g.send(hello)) #結果 = 第一個 ~~ hello #這裏結果出現了hello說明參數傳進去了 == 第二個
一個計算戰績平均值的應用
#生成器函數,用來計算戰績平均值 def averge(): count = 0 aver = 0 num = 0 add = 0 while 1: num = yield add += num count += 1 aver = add/count yield aver #持續輸入的函數,用來輸入每局成績 def print_num(): g = averge() while 1: num = int(input('輸入:')) g.__next__() print(g.send(num)) print_num()
預激活裝飾器
#裝飾器做爲持續輸入的函數 #裝飾器爲生成器函數提供用戶輸入 def print_num(func): def inner(*args, **kwargs): g = func(*args, **kwargs) while 1: num = int(input('輸入:')) g.__next__() print(g.send(num)) return g return inner #生成器函數 @print_num def averge(): count = 0 aver = 0 num = 0 add = 0 while 1: num = yield add += num count += 1 aver = add/count yield aver #調用 averge()
yield from
用法
def generator(): a = '12345' b = 'abcde' yield from a yield from b #調用 g = generator() for i in g: print(i) #結果 1 2 3 4 5 a b c d e
list = [i for i in rang(10)] #獲得的結果 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
g = (i for i in range(10)) #生成器 print(g) #結果 <generator object <xxx> at 0x0000000> #一個內存地址 #利用for循環獲取生成器裏的元素 for i in g: print(i) #結果 0 1 2 3 4 5 6 7 8 9
生成器是一個有指針的數據類型,所以循環一遍以後指針在數據以後,沒法再繼續取值
#定義一個生成器函數 def generator(): for i in range(6) yield i g = generator() #生成器 g1 = (i for i in g) g2 = (i for i in g1) print(list(g1)) print(list(g2)) #結果 [0, 1, 2, 3, 4, 5] []