在Python 2中,當函數定義中的return與yield一起出現錯誤。但是對於Python中的這種代碼3.3返回發生器以及Python中的yield 3.3
def f():
return 3
yield 2
x = f()
print(x.__next__())
在函數中使用yield並沒有錯誤。但是,如果調用函數__next__
,則會引發異常StopIteration。爲什麼不只是返回值3
?這個回報是否被忽略?
在Python 2中,當函數定義中的return與yield一起出現錯誤。但是對於Python中的這種代碼3.3返回發生器以及Python中的yield 3.3
def f():
return 3
yield 2
x = f()
print(x.__next__())
在函數中使用yield並沒有錯誤。但是,如果調用函數__next__
,則會引發異常StopIteration。爲什麼不只是返回值3
?這個回報是否被忽略?
這是一項新功能Python 3.3(作爲註釋註釋,它甚至在3.2中不起作用)。就像發電機中的return
長期等效於raise StopIteration()
,發電機中的return <something>
現在相當於raise StopIteration(<something>)
。出於這個原因,你看到的異常應該打印爲StopIteration: 3
,並且該值可以通過異常對象上的屬性value
訪問。如果發生器被委派使用(也是新的)語法,則結果如下。詳情請參閱PEP 380。
def f():
return 1
yield 2
def g():
x = yield from f()
print(x)
# g is still a generator so we need to iterate to run it:
for _ in g():
pass
這將打印1
,但不2
。
除外(不適用python 3.4.3)。 – mcepl
@mcepl謝謝,現在修復。我的例子並沒有真正運行生成器。 – delnan
@mcepl 3.4.3哪部分「不」?我假設你指的是它所說的「如果生成器被委託使用語法中的(也是新的)yield,那就是結果。」我剛剛在3.4.3中試過,並且yield from不會返回「返回的」StopException值,這讓我感到非常奇怪和驚訝。但現在我已經考慮了5秒,這是有道理的,因爲外部發電機在內部發電機完成後繼續運行,並且當外部發電機完成時,它會發出自己的StopIteration;而內發電機發出的氣體漂浮進入乙醚。 – allyourcode
返回值不被忽略,但生成器只有產量值,一個return
只是結束生成器,在這種情況下是早期的。在這種情況下,推進發電機永遠不會達到yield
聲明。
每當迭代器達到要產生的值的'結束'時,必須提出必須。發電機也不例外。對於Python 3.3然而,任何return
表情變得異常的值:
>>> def gen():
... return 3
... yield 2
...
>>> try:
... next(gen())
... except StopIteration as ex:
... e = ex
...
>>> e
StopIteration(3,)
>>> e.value
3
使用next()
功能來推進,而不是直接調用.__next__()
迭代器:
print(next(x))
有趣......如果我嘗試'def f():'就像在Python 3.2.5中那樣,我得到:'SyntaxError:'在參數裏面返回'generator'。 (我知道,3.2.x已經過時了......) – torek
Ive使用Python 3.3.1 – scdmb