Python生成器及send用法講解

2021-09-11 06:47:30 字數 3450 閱讀 7302

我們呼叫乙個普通的python函式時,一般是從函式的第一行**開始執行,結束於return語句、異常或者函式結束(可以看作隱式的返回none)。一旦函式將控制權交還給呼叫者,就意味著全部結束。函式中做的所有工作以及儲存在區域性變數中的資料都將丟失。再次呼叫這個函式時,一切都將從頭建立。 

對於在計算機程式設計中所討論的函式,這是很標準的流程。這樣的函式只能返回乙個值,不過,有時可以建立能產生乙個序列的函式還是有幫助的。要做到這一點,這種函式需要能夠「儲存自己的工作」。 

我說過,能夠「產生乙個序列」是因為我們的函式並沒有像通常意義那樣返回。return隱含的意思是函式正將執行**的控制權返回給函式被呼叫的地方。而"yield"的隱含意思是控制權的轉移是臨時和自願的,我們的函式將來還會收回控制權。

最初的引入是為了讓程式設計師可以更簡單的編寫用來產生值的序列的**

▲.生成值的序列

處理無限序列==>占用記憶體太大==>遇到問題:函式只有一次返回結果的機會,因而必須一次返回所有的結果==>如果get_primes可以只是簡單返回下乙個值,而不是一次返回全部的值

乙個生成器函式的定義很像乙個普通的函式,除了當它要生成乙個值的時候,使用yield關鍵字而不是return。如果乙個def的主體包含yield,這個函式會自動變成乙個生成器(即使它包含乙個return)。除了以上內容,建立乙個生成器沒有什麼多餘步驟了。

△生成器就是一類特殊的迭代器。作為乙個迭代器,生成器必須要定義一些方法(method),其中乙個就是next()。如同迭代器一樣,我們可以使用next()函式來獲取下乙個值。

while迴圈是用來確保生成器函式永遠也不會執行到函式末尾的

pep 342加入了新的特性

通過send方法來將乙個值」傳送「給生成器。other = yield foo 這樣的語句的意思是,"返回foo的值,這個值返回給呼叫者的同時,將other的值也設定為那個值

def get_primes(number):

while true:

if is_prime(number):

number = yield number

number += 1

通過這種方式,我們可以在每次執行yield的時候為number設定不同的值。現在我們可以補齊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))

def get_allprimes(num):

while true:

if prime_num(num):

print('num',num)

other = yield num

print('other',other)

num += 1

gene = get_allprimes(34)

gene.send(none)

gene.send(61)

output:

>>>num 37

>>>other 61

>>>num 41

摘要:send()的作用是使xx賦值為傳送的值(send的引數),然後讓生成器執行到下個yield..

使用send(params)需要區分情況。△注意:如果生成器未啟動,則必須在使用send()前必須要啟動生成器,而啟動的方法可以是generator.next()或是generator.send(none)執行到第乙個yield處.之後就可以使用send(params)不斷傳入值了。如果是已啟動,則send(params)的作用就是給xx賦值為傳送的值(send的引數),然後讓生成器執行到下個yield..

為什麼需要send(none),也很好理解,因為 生成器還沒有走到第乙個yield語句,如果我們發生乙個真實的值,這時是沒有人去「接收」它的。一旦生成器啟動了,就物件接受(即=號左邊的左值xx接受了),之後就可以使用send(params)不斷傳入值了

▲注意,每次的send()都會執行到yield語句,但賦值不會執行,只會有返回值,相當於return後就退出函式了,所以在返回值之後的賦值就不會執行了。

在我看來send()的作用是在next()的基礎上,多了個給xx賦值的功能。如第二次的gene.send(61)先從上次停住的yield處開始執行,使other 賦值為61,然後執行到下乙個yield處===>可以看出當send方法的引數為none時,它與next方法完全等價

more(給還未懂的人更詳細的講解):

def gene():         #生成器函式

print("ok")

x = 100

print(x)

first = yield 50 #這裡就是send函式的關鍵

# send所傳遞的值其實就是給 =號左邊的左值賦值

print(first)

second = yield x # 這裡試第二個斷點

print(second)

z = 'third'

third = yield z

print(third)

inst = gene() #建立生成器物件

output1 = inst.send(none) #啟動生成器,執行到第乙個yield

print(output1) #這邊的output1獲得的是yield的返回值 50

output2 = inst.send(30)

print(output2)

output3 = inst.send(none)

output:

>>>ok

>>>100 ==>print(x)

>>>50 ==>print(output1)

>>>30 ==>send(30)後first被賦值為30然後print(first)

>>>100 ==>print(output2) ==>output = x==100

>>>none ==>send(none)second被賦值為none,print(second)==>none

Python筆記 生成器方法send

日期 20170926 生成器內有乙個方法send,可再次傳入乙個值。上面那句可能聽不懂,但是不要緊,我們先來看看 usr bin python3 defmygenerator value yield 1yield value return done gen mygenerator print ne...

python 生成器即send()用法

作者首先介紹了生成器的作用 是為了讓程式設計師可以更簡單的編寫用來產生值的序列的 然後又介紹了一些其他知識。然後介紹了send是pep 342加入的新特性 通過 send 方法來將乙個值 傳送 給生成器。other yield foo 這樣的語句的意思是,返回 foo 的值,這個值返回給呼叫者的同時...

生成器中的send

import time def foo print start print this is the first line r1 yield r1 print this is the second value s r1 r2 yield r2 print this is the third value...