1. 程式人生 > >Python協程中生成器send方法的使用

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'

時賦值給value。那下面那個yield是幹嘛用的呢?當然是將value的值返回了。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)來實現。

好了,今天的分享就到這裡了,如果你有任何不懂的問題,可以發信息或者留言嘍。