任何函数带 yield都会自动转换成生成器
例子:
def foo_func():
print "> May not be printed this line" (1)
exit()
yield "> This is generator"
foo_func()
调用 foo_func() 会发现 第(1)行不会打印
这是因为
关键字 yield 一旦出现在函数内部 函数就会自动转为一个生成器,生成器只有使用next方法才会被调用
如上
x = foo_func()
print(next(x))
生成器内置迭代器,请看:
dir(x) #x是一个生成器
[
'__class__', '__del__', '__delattr__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__',
'__le__', '__lt__', '__name__', '__ne__', '__new__',
'__next__', '__qualname__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__',
'close', 'gi_code', 'gi_frame', 'gi_running',
'gi_yieldfrom', 'send', 'throw'
]
生成器对象实现了 iter 协议,因此它是可迭代对象,可以使用for Loop迭代
例子:
def one_to_ten():
val = 1
while val <= 10:
#print val
yield val
val += 1
for ele in one_to_ten():
print ele
-
生成器 是一种特殊的迭代器
-
一旦一个函数中包含了关键字 yield 那么它就会自动转化为一个生成器
-
生成器有异于一般函数的使用方式
神奇的yield
当一个生成器函数的 yield 被调用的时候,函数的内部状态就被“冻结”起来,函数内部的变量和值被保存起来。
下一行的代码直到next()方法调用才会再次被执行
next执行的时候,生成器在它上次被中断的地方恢复所有状态,并继续执行,直到下一个yield出现
def is_prime(number):
if number == 2:
return True
i = 2
while i * i <= number:
if number % i == 0:
return False
i += 1
else:
return True
def get_prime(number):
while True:
if is_prime(number):
yield number
number += 1
for element in get_prime(2):
print(element)
记住这些:
- generators 用来生成一系列的值
- yield 在生成器中的作用类似于 return;区别在于,yield保存了函数的局部状态,但return在函数中,会转移控制权,导致整个函数内部丢失所有状态
- 生成器是一种特殊的迭代器(即它实现了内部协议 iter)因此像迭代器一样,生成器可以用next()得到下一个值
网友评论