<?xml version="1.0" encoding="utf-8"?>
generator
1 Python中的generator学习
- Iteration
- generator
- Iteration和generator的区别
- 多线程支持情况
1.1 Iteration
- For语句使用Iteration在Python中for语句迭代的数据都是支持Iteration协议的如:
for x in [1,2,3,4]: print x, .... 1 2 3 4
- Iteration的其它使用情况
- 函数入参为Iterable类型sum(s), min(s), max(s)
- 构造函数list(s), tuple(s), set(s), dict(s)
- in操作符item in s
- Iteration协议
- 拥有_iter_方法
- 拥有next方法
如:
In [10]: items = [1,3,7] In [11]: it = iter(items) In [12]: it.next() Out[12]: 1 In [13]: it.next() Out[13]: 3 In [14]: it.next() Out[14]: 7 In [15]: it.next() --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) /home/rcy/lib/python2.7/site-packages/django/core/management/commands/shell.pyc in <module>() ----> 1 it.next() StopIteration:
- 翻议for语句
for x in obj: # statements <==> _iter = iter(obj) while 1: try: x = _iter.next() except StopIteration: break # statements
- 自定议的iteration类型
class Range(object): def __init__(self, num, start = 0, step = 1): self.index = start self.step = step self.end = num def __iter__(self): return self def next(self): if self.index >= self.end: raise StopIteration r = self.index self.index += self.step return r for x in Range(10): print x,
1.2 Generator
Generator是返回值为序列的函数如:
def Range(num, start=0,step=1): while start < num: yield start start += step for x in Range(10): print x
Generator函数在调用时并不会运行如:
def Range(num, start=0,step=1): print "Hello generation" while start < num: yield start start += step x = Range(10)
Generator函数返回对象拥有next函数,在调用next函数时开始运行,并且到第一个yield语句返回值,并暂停运行,在下一次调用next时再次运行.如:
x = Range(10) # 这里并没有print "Hello generation" x.next() "Hello generation" 0 x.next()
当generator函数返回时,迭代结束
x.next() 9 x.next() --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) /home/robin/Env/mezproj/lib/python2.7/site-packages/django/core/management/commands/shell.pyc in <module>() ----> 1 x.next() StopIteration:
generator除了可以使用yield函数实现,也可以使用下面方法
a = [1,2,3,4,5] b = (x*x for x in a) # 这里x为generator
(expression for i in s if cond1 for j in t if cond2 ... if condfinal) <==> for i in s: if cond1: for j in t: if cond2: ... if condfinal: yield expression
generator的中断方法调用throw GeneratorExit
def close_generator(gen): try: gen.throw(GeneratorExit) except (GeneratorExit, StopIteration): pass else: raise RuntimeError("generator ignored GeneratorExit")
1.3 Iteration和generator的区别
generator是一次性运算,并不能反复使用;Iteration生成对象可以多次使用generator还可以同过调用send函数往object内部传值,而iterable对象是没有send函数的
def hello(): print "Hello" x = yield 1 print " ", x y = yield 2 print " over with ",y h = hello() m = h.next() # or h.send(None), not h.send(msg)send传值时必序在yield中断时 print m n = h.send('robin') print n h.send('success')