python 學習彙總35:生成器-generator( tcy)
生成器-generator 2018/7/7
生成器是一個函式,生成一個值的序列,用在迭代和容器 1.1性質
1) 生成器是迭代器儲存是演算法,每次迭代返回一個值,遇到StopIteration結束
2) 生成器函式跟普通函式區別:
把return換成yield,yield內部實現迭代器協議,同時保持狀態可以掛起。
yield是資料生產者,諸如for等是資料消費者
3)生成器執行 :
next,for ,檢索生成器元素如list(generator), 當需要資料時才會執行。
4)值傳遞給生成器
val=(yield i)括號不是必要;yield表示式必須加括號val=(yield i)+12
1.2.定義yield element
任何使用yield的函式都成為生成器。呼叫生成器函式將建立一個物件
生成器屬性
屬性 g.gi_code 生成器函式程式碼物件 g.gi_frame 生成器函式的執行幀 g.gi_running 顯示生成器函式目前是否真正執行的整數 方法 g.__next__(),next() 執行函式直到遇到下一條yield語句為止,並返回值; 等價於send(None) g.send(value) 值傳送到生成器; 恢復生成器的程式碼, yield表示式返回指定的值。 如果__next__()呼叫常規方法則yield返回None。 # g.throw(exc,exc_value,exc_tb)語句消耗掉一個yield g.throw(type, value=None, traceback=None) 在發生器內引發異常; type=exception傳入一個異常,在當前yield語句處引發 g.close() 關閉生成器,丟擲GeneratorExit或StopIteration
例項1:send()方法 :
send 方法:外部作用域訪問生成器 引數(要傳送的“訊息”任意物件) def gener_fun(): value=0 while True: new=yield value if new=='e': break value = 'new= %s' % new # 呼叫: g=gener_fun() print(g.send(None)) print(g.send('first')) print(g.send(2)) try: print(g.send('e')) except StopIteration: print('StopIteration!')
例項2:無窮奇數
def odd(long=1):
n=long
while True:
yield n
n+=2
# 呼叫:
data = odd(1)
for count in data:
if count >=10: break
print(count)#1,3,5,7,9
例項3:遞迴
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
例項4:生成器關閉close()
def g4():
yield 1
yield 2
# 呼叫:
g=g4()
next(g) #1
g.close()
next(g) #關閉後,yield 2語句將不再起作用返回異常StopIteration
例項5:工作原理
def generator():
print ('begin=: generator')
i = 0
while True:
print ('before return= ', i )
yield i
i += 1
print ('after return= ', i )
# 呼叫:
g = generator()#generator object
next(g) #開始執行
#begin=: generator
#before return= 0
next(g) #after return= 1
#before return= 1
另一個例項
throw()後直接丟擲異常並結束程式,或消耗掉一個yield,或在沒有下一個yield的時候直接進行到程式的結尾
def gener_fun():
while True:
try:
yield '1.first...'
yield '2.two...'
print('3.three...')
except ValueError:
print('4.ValueError...')
except TypeError:
break
# 呼叫:
g=gener_fun()
print(next(g))
print(g.throw(ValueError))
print(next(g))
try:
print(g.throw(TypeError))
except StopIteration:
print('5.ValueError...')
# 1.first...
# 4.ValueError...
# 1.first...
# 2.two...
# 5.ValueError...
例項6:2Dlist資料
def data(lst):
for sublist in lst:
for element in sublist:
yield element #每次產生多個值
# 呼叫:
lst = [[1, 2], [3]]
for num in data(lst):
print( num )
例項:普通函式模擬生成器
def data(lst):
result = [] #函式體開始處
try: # 不要迭代類似字串的物件:
try: lst + ""
except TypeError:pass
else:
raise TypeError
for sublist in lst:
for element in data(sublist):
result.append(element) #替換生成器表示式
except TypeError:
result.append(lst)
return result #函式末尾