genorator python理解
完全理解可迭代类型,迭代器,生成器
谈谈python的生成器
[Python高级编程(第二版)]
python Standard Library
前面讨论了迭代器,这里继续讨论genorator(生成器),这两种python语法都是一种有用的方式.这两种方式生成元素,序列在其调用的时候,这样不用在内存中存储容器(这个特点在容器很大的时候比较有用)
我们来讨论这两种方式:
- Iterator:
class Iterat:
def __init__(self.step):
self.step = step
def __iter__(self):
return self
#def __next__(self): #for python3.x
def next(self): #for python2.x
if self.step <= 0:
raise StopIteration
self.step -= 1
return self.step
ITER = Iterat(3)
for element in ITER:
print(element)
- Genorator:
def genorate(n):
while True:
if n <= 0:
raise StopIteration
yield n
n -= 1
gen = genorate(n)
for i in gen:
print(i)
这两种方式都会得到同样的结果.但是生成器明显在代码复杂度上面要小于迭代器,对比,我们可以发现要使用迭代器,我们必须创建一个可迭代的类,类中要包含__iter__(),next()(或者for python2.x,next()方法),而在产生生成器的时候,只用改动很少的一点代码,使用yield关键字.
yield 关键字
每次执行迭代器next()方法并返回后,该方法的上下文环境即消失了,而对于生成器,每次执行next()方法后,代码会执行到yield关键字处,将yield后的参数值返回,同时保存当前生成器函数的上下文.也就是1)保存了该函数中当时所有的变量状态,同时2)函数代码执行到的位置也被保留.就像是函数被暂停.当下一次调用或者next()的时候,代码会从yield关键字的下一行开始执行,如果执行next()没有遇到yield关键字就会退出,并抛出StopIteration异常.
同时我们需要提到的生成器方法除了next(),还有
- close()方法,可关闭生成器:
gen = (x for x in range(5))
gen.close()
gen.next() #StopIteration
- send()方法
可以向生成器内部传递参数.
def count(n):
x = 0
while x < n:
value = yield x
if value is not None:
print 'Received value: %s' %value
x += 1
gen = count(5)
print gen.next() #print 0
print gen.send('Hello') #Received Value: Hello, then print 1
- throw()方法
我们可以向生成器函数内部传递参数,还可以传递异常