python中有乙個非常有用的語法叫做生成器,所利用到的關鍵字就是yield。有效利用生成器這個工具可以有效地節約系統資源,避免不必要的記憶體占用。
def fun():
for i in range(20):
x=yield i
print('good',x)
if __name__ == '__main__':
a=fun()
a.__next__()
x=a.send(5)
print(x)
這段**很短,但是詮釋了yield關鍵字的核心用法,即逐個生成。在這裡獲取了兩個生成器產生的值,即0和1。分別由next函式和send()函式獲得,這兩個函式的區別我們後面會詳細闡述。
關於__next__函式,這裡先說明一下,我們可以利用__next__()這個函式持續獲取符合fun函式規則的數,直到19結束。這段**如下所示:
def fun():
for i in range(20):
x=yield i
if __name__ == '__main__':
for x in fun():
print(x)
這段**的效果和下面這段**是完全相同的
if __name__ == '__main__':
for i in range(20):
x=yield i
for..in呼叫生成器算是生成器的基礎用法,不過只會用for..in意義是不大的。生成器中最重要的函式是sent和__next__這兩個函式,下面就針對這兩個函式進行詳細的闡述。
這裡特別強調了sent函式,因為sent函式沒有那麼直觀。__next__函式很好理解,就是從上乙個終止點開始,到下乙個yield結束,返回值就是yield表示式的值。
例如在初始的那段**裡:
def fun():
for i in range(20):
x=yield i
print('good',x)
第一次呼叫__next__函式的時候,我們從fun的起點開始,然後在yield處結束,需要注意的是,賦值語句不會呼叫,此處yield i和含義和return差不多。
但是第二次呼叫__next__函式的時候,就會直接從上乙個yield的結束處開始,也就是先執行賦值語句,然後輸出字串,進入下乙個迴圈,直到下乙個yield或者生成器結束
再次看初始的那段**,可以發現第二次呼叫的時候沒有選擇使用__next__函式,而是使用了乙個sent()函式。這裡就需要注意,sent()函式的用法和__next__函式不太一樣。sent()函式只能從yield之後開始,到下乙個yield結束。這也就意味著第一次呼叫必須使用__next__函式。
sent()函式最重要的作用在於它可以給yield對應的賦值語句賦值,比如上面那一段**中的
x=yield i
如果呼叫__next()__函式,那麼x=none。但是如果呼叫sent(5),那麼x=5。除了上述將的兩個特徵以外,sent和next並沒有什麼區別,sent函式也會返回yield表示式對應的值
需要特別注意的是,儘管是生成器。但是next函式的呼叫次數可能是有限的。比如下面這段**
def fun():
for i in range(20):
x=yield i
print('good',x)
if __name__ == '__main__':
a=fun()
for i in range(30):
x=a.__next__()
print(x)
生成器裡的函式只迴圈了20次,但是next函式卻呼叫了30次,這時候就會觸發stopiteration異常。 解析Python中的yield關鍵字
前言 python中有乙個非常有用的語法叫做生成器,所利用到的關鍵字就是yield。有效利用生成器這個工具可以有效地節約系統資源,避免不必要的記憶體占用。一段 def fun for i in range 20 x yield i print good x if name main a fun a....
解析Python中的yield關鍵字
python中有乙個非常有用的語法叫做生成器,所利用到的關鍵字就是yield。有效利用生成器這個工具可以有效地節約系統資源,避免不必要的記憶體占用。def fun for i in range 20 x yield i print good x if name main a fun a.next x...
關於Python中的yield
在介紹yield前有必要先說明下python中的迭代器 iterator 和生成器 constructor 一 迭代器 iterator 在python中,for迴圈可以用於python中的任何型別,包括列表 元祖等等,實際上,for迴圈可用於任何 可迭代物件 這其實就是迭代器 迭代器是乙個實現了迭...