Python 为什么可以';t切换函数生成器';是什么行为引起了争论?
考虑这两个功能:Python 为什么可以';t切换函数生成器';是什么行为引起了争论?,python,python-3.x,generator,Python,Python 3.x,Generator,考虑这两个功能: 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:
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)]=
但是,如果gen=False
,则不会生成任何内容
In [1351]: [num for num in wrap_foo(gen=False)]
Out[1351]: []
Python似乎根据yield
语句的存在将函数预先分类为生成器(如果yield
被注释掉,后一个示例非常有效)
为什么会这样?我想了解在这里起作用的机制。我在跑3.6
Python似乎根据yield语句的存在将函数预先分类为生成器
是的,事情就是这样<代码>换行符在函数定义时被确定为生成器。您可以考虑使用生成器表达式代替:
def wrap_foo(limit=10, gen=True):
fg = foo()
if gen:
return (next(fg) for _ in range(limit))
else:
return [next(fg) for _ in range(limit)]
Python似乎预先将函数分类为基于生成器的函数
如果存在收益率声明(后一个示例非常有效)
如果收益率被注释掉)
为什么会这样
因为Python不能等到函数实际执行一个
yield
来决定它是否是生成器。首先,生成器被定义为在第一个next
之前不执行任何代码。第二,如果生成器碰巧没有生成任何元素,那么它可能永远不会实际到达任何yield
语句。如果def
主体中有yield
,则函数将始终是生成器。返回
随后将作为隐式的停止迭代
,而不是典型的返回
值。如果您想将整个内容加载到内存中,只需使用list(wrap_foo(10))
。你为什么要用别的方法?我就是这么想的。我只是在我的交互式shell中的某个点上变懒了,尝试添加一个kwarg,这样我就可以直接获取生成的数据,而不是总是调用[\uuuu]for\uu in…
,然后我对我为什么不能这样做感到好奇。但是你不需要调用[\uu]for\uu in…]
,您已经将该逻辑抽象到生成器中,所以要具体化它,只需使用列表
非常正确。我只是在夸张;-)
def wrap_foo(limit=10, gen=True):
fg = foo()
if gen:
return (next(fg) for _ in range(limit))
else:
return [next(fg) for _ in range(limit)]