简单简单简单yield
计算 fibonacci 序列的基础方法,解释如下:
def fib(limit=50):
a, b = 0, 1
for i in range(limit):
yield b
a, b = b, a+b
当你把这个输入你的REPL,然后尝试把它称为, 你会得到一个神秘的结果:
>>> fib()
<generator object fib at 0x7fa38394e3b8>
这是因为:yield
发送到 Python 的信号, 您想要创建发电机发电机,即,一个根据需求产生价值的物体。
那么,您如何生成这些值? 可以通过使用内置函数直接实现next
,或间接地,通过将其喂养到消耗价值的建筑上。
使用内置next()
函数,直接引用.next
/__next__
迫使发电机产生一个价值:
>>> g = fib()
>>> next(g)
1
>>> next(g)
1
>>> next(g)
2
>>> next(g)
3
>>> next(g)
5
间接提供fib
至 afor
环环, alist
初始初始化器, atuple
初始化器, 或其他任何期望生成/ 产生值的对象, 您会“ 组装” 生成器, 直到它无法生成更多值( 并返回 ) :
results = []
for i in fib(30): # consumes fib
results.append(i)
# can also be accomplished with
results = list(fib(30)) # consumes fib
同样,tuple
初始化器 :
>>> tuple(fib(5)) # consumes fib
(1, 1, 2, 3, 5)
生成器与功能不同, 因为它很懒。 它通过保持本地状态, 并允许您在需要的时候恢复运行来达到这个目的 。
当你们第一次祈祷的时候,fib
称其为:
f = fib()
Python 编译函数,遇到yield
keyword and simply return a generate objects back at you. 似乎没有什么帮助。
当您要求它生成第一个值时,它直接或间接地执行它发现的所有语句,直到它遇到一个yield
,然后,它产生回 价值,你提供yield
并暂停。 举例来证明这一点, 让我们使用一些print
电话(取代电话)print "text"
如果Python 2 上写着:
def yielder(value):
""" This is an infinite generator. Only use next on it """
while 1:
print("I'm going to generate the value for you")
print("Then I'll pause for a while")
yield value
print("Let's go through it again.")
现在,输入REPL:
>>> gen = yielder("Hello, yield!")
您现在有一个生成对象, 正在等待命令来生成值。 使用next
并查看打印的内容 :
>>> next(gen) # runs until it finds a yield
I'm going to generate the value for you
Then I'll pause for a while
'Hello, yield!'
未引用的结果是打印的内容。引用的结果是返回的内容yield
调来next
现在再次:
>>> next(gen) # continues from yield and runs again
Let's go through it again.
I'm going to generate the value for you
Then I'll pause for a while
'Hello, yield!'
发电机记得它被停停在yield value
从那里打印下一条消息并搜索yield
暂停该语句时(由于while
(循环))