Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么可以';t切换函数生成器';是什么行为引起了争论?_Python_Python 3.x_Generator - Fatal编程技术网

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)]