簡體   English   中英

在生成器中返回和不返回:PEP准則

[英]return and return None in a generator: PEP guidelines

根據PEP 8,我們應該在函數聲明中保持一致,並確保它們都具有相同的return-pattern,即,所有人都應該返回一個表達式,否則所有人都應該不返回一個表達式。 但是,我不確定如何將此應用於發電機。

只要代碼到達它們,生成器就會yield值,除非遇到return語句,在這種情況下它將停止迭代。 但是,我看不到有任何用例可以從生成器函數返回值的情況。 本着這種精神,我不明白為什么從PEP 8的角度來看,用顯式return None結束這樣的功能是有用的。 換句話說,如果僅在yieldinging結束時才返回return表達式,為什么還要對生成器的return語句進行口頭表達呢?

示例:在以下代碼中,我看不到如何使用hello()100分配給變量(因此使用return語句)。 那么,為什么PEP 8期望我們編寫一個return語句(無論是100還是None )。

def hello():
    for i in range(5):
      yield i

    return 100


h = [x for x in hello()]
g = hello()

print(h)    
# [0, 1, 2, 3, 4]
print(g)
# <generator object hello at 0x7fd2f285a7d8>
# can we ever get 100?

您誤讀了PEP8。 PEP8指出:

在返回語句中保持一致。 函數中的所有return語句應返回一個表達式,或者都不返回。

(加粗強調我的)

您應該與在單個函數(而不是整個項目)中使用return方式保持一致。

使用return ,它是函數中唯一的return語句。

但是,我看不到有任何用例可以從生成器函數返回值的情況。

生成器的返回值附加到引發的StopIteration異常上:

>>> def gen():
...     if False: yield
...     return 'Return value'
...
>>> try:
...     next(gen())
... except StopIteration as ex:
...     print(ex.value)
...
Return value

這也是yield from產生價值的機制。 yield from的返回值是StopIteration異常上的value屬性。 因此,生成器可以使用result = yield from generator通過使用return resultresult = yield from generator返回到代碼:

>>> def bar():
...     result = yield from gen()
...     print('gen() returned', result)
...
>>> next(bar(), None)
gen() returned Return value

Python標准庫中使用了此功能。 例如,在asyncio庫中, StopIteration的值用於傳遞Task結果,而@coroutine裝飾器使用res = yield from ...來運行包裝的生成器或可等待的生成器並傳遞返回值。

因此,從PEP-8的角度來看,對於發電機而言,有兩種可能性:

  • 您正在使用return提早退出生成器,例如在if循環中說。 使用return ,無需添加None

     def foo(): while bar: yield ham if spam: return 
  • 您正在使用return <something>退出設置StopIteration.value 即使在返回None ,在整個生成器中始終使用return <something>

     def foo(): for bar in baz: yield bar if spam: return 'The bar bazzed the spam' return None 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM