【发布时间】:2022-01-20 18:41:11
【问题描述】:
给定一个带有返回值的简单生成器:
def my_generator():
yield 1
yield 2
return 3
我正在寻找一个简单的函数,它返回生成的列表和返回值。
>>> output_and_return(my_generator())
([1, 2], 3)
似乎没有任何干净的方法可以做到这一点。在另一个生成器中,您可以使用value = yield from my_generator(),它会为您获取返回值,但不会直接为您提供输出列表本身。
我能想到的最接近的方法是将它包裹在一个捕获返回值的迭代器上:
class Generator:
def __init__(self, gen):
self.gen = gen
def __iter__(self):
self.value = yield from self.gen
def output_and_return(self):
return list(self), self.value
Generator(my_generator()).output_and_return()
这很有效,但绝不简单或干净。有谁知道一种更简单的方法来提取值列表以及生成器的返回值而不将其包装在另一个类中?
【问题讨论】:
-
你不能两者兼得。函数要么是生成器,要么具有正常返回。你为什么不直接做正确的事,然后把
return变成yield呢? -
实际上从 Python 3.3 开始,生成器中的
return <something>现在等同于raise StopIteration(<something>)。见PEP 380 和Return in generator together with yield in Python 3.3 -
我不知道你为什么称这是对语言的滥用,这不是一个很好的模式,但它有一些有限的用例。
-
以上所有 cmets 都说这是对语言的滥用,这是公然错误的。这是规范的一部分,查看 PEP255 和打字信息docs.python.org/3/library/typing.html#typing.Generator
-
我编辑了 PEP 380 的自我更正,现在从 3.3 开始允许这样做。还有PEP 479:
raise StopIteration处于弃用计划中,What is the difference between raise StopIteration and a return statement in generators?