返回不同类型的Yield vs生成器表达式

2024-03-28 15:06:51 发布

您现在位置:Python中文网/ 问答频道 /正文

有这样的代码:

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

当有返回生成器语句时,为什么f返回{}?我想yield和generator expression都返回generator(至少在删除return 3语句时),但是当有一次生成器表达式返回,第二次有yield关键字时,函数编译还有其他规则吗?在

这在python3.3中进行了测试


Tags: 代码inforreturn表达式deftyperange
3条回答
def f():
  return 3
  return (i for i in range(10))

^{pr2}$

第二个return语句永远不会被执行,只是在f中有一个生成器表达式并不能使它成为生成器。在

当您在函数体中使用yield语句时,它就变成了生成器。调用生成器函数只返回生成器对象。它不再是一个正常的函数,而是由generator对象接管了控制权。在

^{} expression documentation

Using a yield expression in a function definition is sufficient to cause that definition to create a generator function instead of a normal function.

When a generator function is called, it returns an iterator known as a generator. That generator then controls the execution of a generator function. The execution starts when one of the generator’s methods is called.

在常规函数中,调用该函数会立即将控制权切换到该函数体,而您只需测试函数的结果,该结果由它的return语句设置。在生成器函数中,return仍然表示生成器函数的结束,但这会导致引发StopIteration异常。但是,除非调用4个生成器方法(.__next__().send().throw().close())中的一个,否则生成器函数体根本不会执行。在

对于您的特定函数f(),您有一个正则函数,包含一个生成器。该函数本身没有什么特别之处,只是它在return 3执行时提前退出。下一行的生成器表达式是独立的,它不影响定义它的函数。您可以在不使用函数的情况下定义它:

>>> (i for i in range(10))
<generator object <genexpr> at 0x101472730>

使用生成器表达式生成生成器对象,就像在函数中使用yield,然后调用该函数生成生成器对象。因此,您可以在f()中调用g(),其结果与使用生成器表达式的结果相同:

^{pr2}$

g()仍然是一个生成函数,但是在f()中使用它不会使f()也成为生成函数。只有yield可以做到这一点。在

def f():
  return 3
  #unreachable code below
  return (i for i in range(10))

我相信你的意思是:

^{pr2}$

相关问题 更多 >