在 Python 中获得生成器的 yield'ed 输出和 return'ed 值的最佳方法
Best way of getting both the yield'ed output and return'ed value of a generator in Python
给定一个具有 return 值的简单生成器:
def my_generator():
yield 1
yield 2
return 3
我正在寻找一个简单的函数,它 return 生成的列表和 return 值。
>>> output_and_return(my_generator())
([1, 2], 3)
似乎没有任何干净的方法可以做到这一点。在另一个生成器中,您可以使用 value = yield from my_generator()
,这将为您提供 return 值,但不会直接为您提供输出列表本身。
我能想到的最接近的方法是将它包装在一个迭代器周围,该迭代器捕获 return 值:
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 值而不将其包装在另一个 class 中?
我想我们可以像这样从 StopIteration
异常中提取它:
def output_and_return(iterator):
output = []
try:
while True:
output.append(next(iterator))
except StopIteration as e:
return output, e.value
不是最干净的代码,但比 class 替代代码好很多。
without wrapping it inside another class?
也许只用一个函数代替?
版本 1:
def output_and_return(it):
def with_result():
yield (yield from it)
*elements, result = with_result()
return elements, result
版本 2:
def output_and_return(it):
result = None
def get_result():
nonlocal result
result = yield from it
return list(get_result()), result
给定一个具有 return 值的简单生成器:
def my_generator():
yield 1
yield 2
return 3
我正在寻找一个简单的函数,它 return 生成的列表和 return 值。
>>> output_and_return(my_generator())
([1, 2], 3)
似乎没有任何干净的方法可以做到这一点。在另一个生成器中,您可以使用 value = yield from my_generator()
,这将为您提供 return 值,但不会直接为您提供输出列表本身。
我能想到的最接近的方法是将它包装在一个迭代器周围,该迭代器捕获 return 值:
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 值而不将其包装在另一个 class 中?
我想我们可以像这样从 StopIteration
异常中提取它:
def output_and_return(iterator):
output = []
try:
while True:
output.append(next(iterator))
except StopIteration as e:
return output, e.value
不是最干净的代码,但比 class 替代代码好很多。
without wrapping it inside another class?
也许只用一个函数代替?
版本 1:
def output_and_return(it):
def with_result():
yield (yield from it)
*elements, result = with_result()
return elements, result
版本 2:
def output_and_return(it):
result = None
def get_result():
nonlocal result
result = yield from it
return list(get_result()), result