根据PEP 8,我们应该在函数声明中保持一致,并确保它们都具有相同的返回模式,即所有应该返回一个表达式,或者所有都不应该。但是,我不知道如何将其应用于发电机。
只要代码到达它们,生成器将yield
值,除非遇到return
语句,在这种情况下它将停止迭代。但是,我没有看到任何用例从生成器函数返回值的用例。本着这种精神,我不明白为什么从PEP 8的角度来看,用明确的return None
来结束这样的功能是有用的。换句话说,如果仅在收益率结束时达到回报表达式,为什么我们应该用语言表示生成器的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?
答案 0 :(得分:2)
你误读了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
的返回值是value
例外的StopIteration
属性。因此,生成器可以使用result = yield from generator
:
return result
将结果返回给代码
>>> 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
。在整个生成器中始终使用return <something>
,即使返回None
:
def foo():
for bar in baz:
yield bar
if spam:
return 'The bar bazzed the spam'
return None