一旦你在函数体中使用了一个语句yield
,它就变成了一个生成器。调用生成器函数只会返回该生成器对象。它不再是正常功能;生成器对象已接管控制权。
从yield
表达式文档:
在函数定义中使用yield
表达式足以使该定义创建生成器函数而不是普通函数。
当调用生成器函数时,它返回一个称为生成器的迭代器。然后该生成器控制生成器函数的执行。当调用生成器的方法之一时开始执行。
在常规函数中,调用该函数会立即将控制权切换到该函数体,您只是在测试函数的结果,由它的return
语句设置。在生成器函数中,return
仍然发出生成器函数结束的信号,但这会导致StopIteration
引发异常。但在您调用 4 个生成器方法之一(.__next__()
、、或)之前.send()
,生成器函数体根本不会执行。.throw()
.close()
对于您的特定功能f()
,您有一个常规功能,其中包含一个生成器。该函数本身并没有什么特别之处,只是它在return 3
执行时提前退出。下一行的生成器表达式独立存在,它不影响定义它的函数。您可以在没有函数的情况下定义它:
>>> (i for i in range(10))
<generator object <genexpr> at 0x101472730>
使用生成器表达式会生成生成器对象,就像yield
在函数中使用一样,然后调用该函数会生成生成器对象。因此,您可以调用g()
与f()
使用生成器表达式相同的结果:
def f():
return 3
return g()
g()
仍然是生成器函数,但在其中使用它f()
也不会生成f()
生成器函数。只能yield
这样做。