Python生成器及send用法讲解
- 生成器
我們調(diào)用一個普通的Python函數(shù)時,一般是從函數(shù)的第一行代碼開始執(zhí)行,結(jié)束于return語句、異常或者函數(shù)結(jié)束(可以看作隱式的返回None)。一旦函數(shù)將控制權(quán)交還給調(diào)用者,就意味著全部結(jié)束。函數(shù)中做的所有工作以及保存在局部變量中的數(shù)據(jù)都將丟失。再次調(diào)用這個函數(shù)時,一切都將從頭創(chuàng)建。?
對于在計算機編程中所討論的函數(shù),這是很標準的流程。這樣的函數(shù)只能返回一個值,不過,有時可以創(chuàng)建能產(chǎn)生一個序列的函數(shù)還是有幫助的。要做到這一點,這種函數(shù)需要能夠“保存自己的工作”。?
我說過,能夠“產(chǎn)生一個序列”是因為我們的函數(shù)并沒有像通常意義那樣返回。return隱含的意思是函數(shù)正將執(zhí)行代碼的控制權(quán)返回給函數(shù)被調(diào)用的地方。而"yield"的隱含意思是控制權(quán)的轉(zhuǎn)移是臨時和自愿的,我們的函數(shù)將來還會收回控制權(quán)。
最初的引入是為了讓程序員可以更簡單的編寫用來產(chǎn)生值的序列的代碼
▲.生成值的序列
處理無限序列==>占用內(nèi)存太大==>遇到問題:函數(shù)只有一次返回結(jié)果的機會,因而必須一次返回所有的結(jié)果==>如果get_primes可以只是簡單返回下一個值,而不是一次返回全部的值
一個生成器函數(shù)的定義很像一個普通的函數(shù),除了當它要生成一個值的時候,使用yield關(guān)鍵字而不是return。如果一個def的主體包含yield,這個函數(shù)會自動變成一個生成器(即使它包含一個return)。除了以上內(nèi)容,創(chuàng)建一個生成器沒有什么多余步驟了。
△生成器就是一類特殊的迭代器。作為一個迭代器,生成器必須要定義一些方法(method),其中一個就是next()。如同迭代器一樣,我們可以使用next()函數(shù)來獲取下一個值。
while循環(huán)是用來確保生成器函數(shù)永遠也不會執(zhí)行到函數(shù)末尾的
PEP 342加入了新的特性
通過send方法來將一個值”發(fā)送“給生成器。other = yield foo 這樣的語句的意思是,"返回foo的值,這個值返回給調(diào)用者的同時,將other的值也設(shè)置為那個值
def get_primes(number):while True:if is_prime(number):number = yield numbernumber += 1通過這種方式,我們可以在每次執(zhí)行yield的時候為number設(shè)置不同的值。現(xiàn)在我們可以補齊print_successive_primes中缺少的那部分代碼:def print_successive_primes(iterations, base=10):prime_generator = get_primes(base)prime_generator.send(None)for power in range(iterations):print(prime_generator.send(base ** power))- 理解send
def Get_allprimes(num):while True:if prime_num(num):print('num',num)other = yield numprint('other',other)num += 1gene = Get_allprimes(34)gene.send(None)gene.send(61)output:>>>num 37>>>other 61>>>num 41★ 重點:看這句xx = yield yy
摘要:send()的作用是使xx賦值為發(fā)送的值(send的參數(shù)),然后讓生成器執(zhí)行到下個yield..
使用send(params)需要區(qū)分情況。△注意:如果生成器未啟動,則必須在使用send()前必須要啟動生成器,而啟動的方法可以是generator.next()或是generator.send(None)執(zhí)行到第一個yield處.之后就可以使用send(params)不斷傳入值了。如果是已啟動,則send(params)的作用就是給xx賦值為發(fā)送的值(send的參數(shù)),然后讓生成器執(zhí)行到下個yield..
為什么需要send(None),也很好理解,因為 生成器還沒有走到第一個yield語句,如果我們發(fā)生一個真實的值,這時是沒有人去“接收”它的。一旦生成器啟動了,就對象接受(即=號左邊的左值xx接受了),之后就可以使用send(params)不斷傳入值了
▲注意,每次的send()都會運行到y(tǒng)ield語句,但賦值不會執(zhí)行,只會有返回值,相當于return后就退出函數(shù)了,所以在返回值之后的賦值就不會執(zhí)行了。
在我看來send()的作用是在next()的基礎(chǔ)上,多了個給xx賦值的功能。如第二次的gene.send(61)先從上次停住的yield處開始運行,使other 賦值為61,然后執(zhí)行到下一個yield處===>可以看出當send方法的參數(shù)為None時,它與next方法完全等價
More(給還未懂的人更詳細的講解):
- send(None)啟動后send(int類參數(shù)),然后再傳個send(None)效果是怎樣的?
每次的send(params)都會運行到y(tǒng)ield語句,但賦值不會執(zhí)行,只會有返回值。賦值在下一次send(params)時將xx賦值為params,執(zhí)行過程如下
只有返回值:
output1接受返回值:
執(zhí)行send(params):
將passvalue賦值為params:
接受運行到的第二個yield的返回值:
參考博客生成器
轉(zhuǎn)載于:https://www.cnblogs.com/nymrli/p/9416949.html
總結(jié)
以上是生活随笔為你收集整理的Python生成器及send用法讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 英伟达Quadro RTX A5000/
- 下一篇: 骨传导耳机有什么危害?骨传导耳机对人体有