产量与发电机表达 - 返回不同类型

scd*_*dmb 4 python yield generator

有这个代码:

def f():
  return 3
  return (i for i in range(10))

x = f()
print(type(x)) # int

def g():
  return 3
  for i in range(10):
    yield i

y = g()
print(type(y)) # generator
Run Code Online (Sandbox Code Playgroud)

为什么要f返回int时,有回报发生器说法?我想这yield和生成器表达式都返回生成器(至少在return 3删除语句时)但是当有一次返回生成器表达式时,还有其他一些函数编译规则,第二次有yield关键字在里面吗?

这是在Python 3.3中测试的

Mar*_*ers 9

由于一旦你使用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>
Run Code Online (Sandbox Code Playgroud)

使用生成器表达式生成一个生成器对象,就像yield在函数中使用一样,然后调用该函数生成一个生成器对象.所以,你可以呼吁g()f()用相同的结果作为使用生成器表达式:

def f():
    return 3
    return g()
Run Code Online (Sandbox Code Playgroud)

g()仍然是一台发电机的功能,但在使用它f()没有使f()发电机的功能了.只能yield这样做.