Python的"产量"行为

Tom*_*ito 10 python yield

我正在阅读yieldpython中的关键字,并试图了解运行此示例:

def countfrom(n):
    while True:
        print "before yield"
        yield n
        n += 1
        print "after yield"

for i in countfrom(10):
    print "enter for loop"
    if i <= 20:
        print i
    else:
        break
Run Code Online (Sandbox Code Playgroud)

输出是:

before yield
enter for loop
10
after yield
before yield
enter for loop
11
after yield
before yield
enter for loop
12
after yield
before yield
enter for loop
13
after yield
before yield
enter for loop
14
after yield
before yield
enter for loop
15
after yield
before yield
enter for loop
16
after yield
before yield
enter for loop
17
after yield
before yield
enter for loop
18
after yield
before yield
enter for loop
19
after yield
before yield
enter for loop
20
after yield
before yield
enter for loop
Run Code Online (Sandbox Code Playgroud)

看起来yield将返回指定的值,并将继续运行该函数直到结束(可能是并行线程).我的理解是否正确?

如果你能在不提及"发电机"的情况下回答这个问题,我会感激不尽,因为我试图一次理解一个.

car*_*ett 23

你可以把它想象成yield当它碰到时简单地"暂停" 的功能yield.下次你调用它时,它会在yield 保持它离开时的状态后恢复.

  • 不,你不再调用该函数以便恢复,你必须在返回的生成器对象上调用`next()`方法. (4认同)
  • @Tom Brito,`next()`由`for`循环在引擎盖下执行.也就是说,"iterable"对象只是一个带有`next()`方法的对象,它应该为它包含的每个项返回一个值,并在到达最后一个项时引发异常 (3认同)

Dav*_*nan 8

不,只有一个线程.

for循环的每次迭代都会运行你的countFrom函数,直到它产生某些东西或返回.在yield之后,for循环的主体再次运行,然后,当一个新的迭代开始时,该countFrom函数准确地从它停止的地方获取并再次运行直到它产生(或返回).

您的示例的此修改版本将有助于更清楚地执行路径执行.

def countfrom(n):
    while n <= 12:
        print "before yield, n = ", n
        yield n
        n += 1
        print "after yield, n = ", n

for i in countfrom(10):
    print "enter for loop, i = ", i
    print i
    print "end of for loop iteration, i = ", i
Run Code Online (Sandbox Code Playgroud)

产量

before yield, n =  10
enter for loop, i =  10
10
end of for loop iteration, i =  10
after yield, n =  11
before yield, n =  11
enter for loop, i =  11
11
end of for loop iteration, i =  11
after yield, n =  12
before yield, n =  12
enter for loop, i =  12
12
end of for loop iteration, i =  12
after yield, n =  13
Run Code Online (Sandbox Code Playgroud)


red*_*dow 6

..你不能在yield不提及发电机的情况下解释声明的含义; 这就像试图解释什么是石头而不提岩石.即:yield语句是负责将正常函数转换为生成器的函数.

虽然你在这里找到了很好的文档:http://docs.python.org/reference/simple_stmts.html#the-yield-statement

..它的简要解释是:

  • 当调用使用yield语句的函数时,它返回一个"生成器迭代器",它有一个.next()方法(可迭代对象的标准)
  • 每次.next()调用生成器的方法时(例如,通过使用for循环迭代对象),都会调用该函数,直到遇到第一个yield.然后暂停函数执行并将值作为.next()方法的返回值传递.
  • 下一次.next()调用时,函数执行将恢复到下一次yield,等等,直到函数返回某些内容.

这样做的一些优点是:

  • 内存使用量减少,因为内存仅为当前生成的值分配,而不是整个返回值列表(通过返回值列表)
  • "realtime"结果返回,因为它们的生成可以传递给调用者而无需等待生成结束(我用它来返回正在运行的进程的输出)

  • 尽管我要使用火花塞和发动机,但您在“相互解释”的比喻中打败了我。这篇较老的文章在概述产量和生成器方面也做得很好:http://www.ibm.com/developerworks/library/l-pycon/index.html (2认同)