生成器是一个包含yield关键字的函数,当yield在函数定义中出现时,函数体中的代码分段执行,每两个yield(除了程序一开始执行的时候只有一个标志程序暂停的yield)之间的程序就是一次执行结果。类似于return,但是和return不同的是,yield返回一个迭代器,而return则意味着停止执行。
我的理解是yield相当于整个程序在每次输出时的断点位置,且标志着断点位置,在程序后续执行时起到程序执行的起点位置的作用。下面先介绍一下Python的几个生成器方法:
a、next()用于依次输出yield之前的内容;
b、send()触发程序执行,输出断点间内容,向断点处输入信息;
c、throw()、close()中断Generator,再次调用next()或者send()会抛出异常。
下面是具体用法及注意事项:
(1)也许是因为Python版本的不同,本例使用的是2.7.10版本,在Python的py文件中使用yield和在IDL中使用结果略微不同,仅仅是yield内容是否输出的差别。在py文件中需要将next()赋值给变量,然后print变量才能输出yield内容,而IDL则是直接输出结果。
在py文件中:
def f():
print 'hello world'
yield 'ok'
c = f()
m = c.next()
print m
如果添加print语句,则仅仅输出hello world,添加后换行后输出ok,即next()仅仅输出yield前的程序输出结果,而将yield的返回值赋给了m。
在IDL中:
>>> def f():
print 'hello world'
yield 'ok'
>>> c = f()
>>> c.next()
hello world
'ok'
(2)send()给断点位置添加新的信息,需要在定义函数中的yield后添加print信息才能输出函数外添加的信息
def f():
print 'hello world'
a = yield 'ok'
print a
print 'hello python'
yield 'right'
c = f()
m = c.next()
c.send('information')
输出结果是:
>>>
hello world
information
hello python
>>>
(3)throw()、close()的中断Generator
def g():
yield 1
yield 2
yield 3
c = g()
m = c.next()
print m
n = c.next()
print n
c.close()
b = c.next()
print b
输出结果是:
>>>
1
2
Traceback (most recent call last):
File "F:\Python\Pythonpro\yield_test.py", line 66, in <module>
b = c.next()
StopIteration
由于程序中断,程序不再继续执行,抛出异常。