Python協程中生成器send方法的使用
關於博主
努力與運動兼備~~~有任何問題可以加我好友或者關注微信公眾號,歡迎交流,我們一起進步!
微信公眾號: 啃餅思錄
QQ: 2810706745(啃餅小白)
寫在前面
博主最近在利用協程寫非同步爬蟲的時候,遇到了一個問題,那就是生成器send方法的使用,今天打算好好研究一下相關內容。
分析過程
程式碼上手
#!/usr/bin/python3
def MyGenerator():
value=yield 'hello'
yield value
return done
gen=MyGenerator()
print(next(gen))
print(gen.send("I am Value"))
相信聰明的你發現了,我們在MyGenerator這個函式裡,使用了兩次yield。比較奇怪的是第一個yield的語句,value=yield ‘hello’,你肯定在想這是幹嘛用的,為什麼要這樣寫?當然,如果你之前沒看過這一語句的,肯定不知道next回到yield後,其實是有一個值的。帶著這個疑問,我們先執行一下程式碼試試看,會有什麼結果出現?
執行一下
hello
I am Value
看到沒有,結果出現了hello和I am Value這兩個字串,所以你就知道了,原來next的作用是啟動了生成器gen,知道到yield 'hello'
print(gen.send("I am Value"))
這行程式碼則是呼叫gen的內部方法send進入gen,而且還帶回來一個值“I am Value”。這時候繼續執行yield 'hello’後的程式碼“value=”,把帶回來的值“I am Value”賦給valu,直到遇到yield value,把value返回。
那麼你是否想說send和next的執行非常像,只不過send可以和生成器互動,傳入一個值,而next則不能。
next啟動生成器
試想一下
現在我們可以考慮這麼一個問題:先不啟動生成器,就使用send方法,結果會是怎樣?還會和原來一樣的結果麼,我們來試一下。
修改程式碼
#!/usr/bin/python3
def MyGenerator():
value=yield 'hello'
yield value
return done
gen=MyGenerator()
print(gen.send("I am Value"))
執行看看
Traceback (most recent call last):
File "F:/Python/untitled/xianchengjincheng/IOxiecheng.py", line 42, in <module>
print(gen.send("I am Value"))
TypeError: can't send non-None value to a just-started generator
分析兩下
看到最後錯誤提示沒,說生成器剛剛開始,無法傳送一個不為None的值。由此可見,在使用生成器時,第一次要傳送一個值為None的變數。 那麼問題來了,為什麼我們通常是用next來啟動生成器呢?是不是這個next就相當於,第一次傳送了一個值為None的變數?
next啟動生成器
#!/usr/bin/python3
def MyGenerator():
value=yield 'hello'
yield value
return done
gen=MyGenerator()
print(next(gen)) # next啟動生成器
print(gen.send("I am Value"))
結果顯示
hello
I am Value
由此可見,確實是這個作用。現在我們試著根據錯誤提示,使用在使用生成器時,第一次要傳送一個值為None的變數
這種方法來試一下。
send(None)啟用生成器
程式碼寫入
#!/usr/bin/python3
def MyGenerator():
value=yield 'hello'
yield value
return done
gen=MyGenerator()
print(gen.send(None)) #send(None)啟動生成器
print(gen.send("I am Value"))
執行一下
hello
I am Value
看到沒有,結果和剛才的完全一樣。
最後總結
在使用生成器時,第一次要傳送一個值為None的變數,而這個要求可以通過使用next或者send(None)來實現。
好了,今天的分享就到這裡了,如果你有任何不懂的問題,可以發信息或者留言嘍。