【发布时间】:2017-07-21 07:20:21
【问题描述】:
考虑这两个函数:
def foo():
x = 0
while True:
yield x
x += 1
def wrap_foo(limit=10, gen=True):
fg = foo()
count = 0
if gen:
while count < limit:
yield next(fg)
count += 1
else:
return [next(fg) for _ in range(limit)]=
foo() 是一个生成器,wrap_foo() 只是限制了生成的数据量。我正在尝试让包装器充当带有gen=True 的生成器,或者充当使用kwarg gen=False 将所有生成的数据直接放入内存的常规函数。
常规的生成器行为如我所料:
In [1352]: [_ for _ in wrap_foo(gen=True)]
Out[1352]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
但是,对于 gen=False,不会生成任何内容。
In [1351]: [num for num in wrap_foo(gen=False)]
Out[1351]: []
似乎 Python 根据 yield 语句的存在将函数预分类为生成器(如果 yield 被注释掉,后一个示例可以完美运行)。
这是为什么?我想了解这里的机制。我正在运行 3.6
【问题讨论】:
-
如果您的
def正文中有yield,则该函数将始终是生成器。然后,return将充当隐式StopIteration,而不是典型的return值。如果您想将整个内容加载到内存中,只需使用list(wrap_foo(10))。您为什么要以其他方式进行操作? -
我就是这么想的。我只是在我的交互式 shell 中的某个时刻变得懒惰并尝试添加一个 kwarg,这样我就可以直接获取生成的数据,而不是总是调用
[_ for _ in ...然后我很好奇为什么我不能这样做。 -
但是您不需要调用
[_ for _ in ...],您已经将该逻辑抽象到生成器中,因此只需使用list实现它即可。 -
非常正确。我只是在戏剧化;-)
标签: python python-3.x generator