迭代器、生成器和装饰器
迭代器iterator
- 
迭代器是一个可以记住遍历的位置的对象
 - 
迭代器只能往前不能后退
 - 
迭代器有两个基本方法
- iter()创建迭代器对象
 - next()输出迭代器的下一个元素
 
 - 
字符串,列表或元组对象都可用于创建迭代器
 - 
l = [1, 2, 3, 4] l_iter = l.__iter__() while True: try: # item = l_iter.__next__() # print(item) print(next(l_iter)) except StopIteration: break #判断range()中是否有__iter__方法和__next__方法,是否是迭代器 print("__iter__" in dir(range(12))) print("__next__" in dir(range(12))) print(isinstance(range(100000000), Iterator)) #1 #2 #3 #4 #True #False #False class MyNumbers: def __iter__(self): self.a = 1 return self def __next__(self): if self.a <= 20: x = self.a self.a += 1 return x else: raise StopIteration myclass = MyNumbers() myiter = iter(myclass) for x in myiter: print(x) 
生成器generator
- 
是一个特殊的迭代器
 - 
使用了yield的函数,每次遇到yield时函数会暂停并保存当前所有的运行信息,返回yield的值,在下一次执行next()方法时从当前位置继续运行。
 - 
返回迭代器对象
 - 
使用生成器实现斐波那契数列
import sys def fibonacci(n): # 生成器函数 - 斐波那契 a, b, counter = 0, 1, 0 while True: if (counter > n): return yield a a, b = b, a + b counter += 1 f = fibonacci(10) # f 是一个迭代器,由生成器返回生成 while True: try: print (next(f), end=" ") except StopIteration: sys.exit() - 
yield from
def gen1(): for c in 'AB': yield c for i in range(3): yield i print(list(gen1())) #['A', 'B', 0, 1, 2] - 
send
# send 获取下一个值的效果和next基本一致 # 只是在获取下一个值的时候,给上一yield的位置传递一个数据 # 使用send的注意事项 ## 第一次使用生成器的时候 是用next获取下一个值 ## 最后一个yield不能接受外部的值 def generator(): print(123) content = yield 1 print('=======',content) print(456) yield 2 g = generator() ret = g.__next__() print('***',ret) ret = g.send('hello') #send的效果和next一样 print('***',ret) #123 #*** 1 #======= hello #456 #*** 2 # #计算移动平均值 def averager(): total = 0.0 count = 0 average = None while True: term = yield average total += term count += 1 average = total/count g_avg = averager() next(g_avg) print(g_avg.send(10)) print(g_avg.send(30)) print(g_avg.send(5)) #10.0 #20.0 #15.0 - 
生成器表达式
laomuji=('鸡蛋%s' %i for i in range(10)) print(laomuji) print(next(laomuji)) #next本质就是调用__next__ print(laomuji.__next__()) print(next(laomuji)) #生成器表达式的应用 print(sum(x ** 2 for x in range(4))) #<generator object <genexpr> at 0x00EAD290> #鸡蛋0 #鸡蛋1 #鸡蛋2 #14 #生成器几乎不占用内存 
装饰器decorator
- 
基本装饰器
import time from functools import wraps def timethis(func): @wraps(func) def wrapper(*args, **kwargs): start = time.time() re = func(*args, **kwargs) end = time.time() print(func.__name__, end-start) return re return wrapper @timethis def count(n): while n > 0: n -= 1 count(30000) #count 0.009998083114624023 - 
可以自主增删的装饰器
import time from functools import wraps def outer(flag): def timethis(func): @wraps(func) def wrapper(*args, **kwargs): if flag: start = time.time() re = func(*args, **kwargs) end = time.time() print(func.__name__, end - start) return re else: return func(*args, **kwargs) return wrapper return timethis @outer(True) #@outer(False) def count(n): while n > 0: n -= 1 print("over") count(30000) #over #count 0.020034313201904297 - 
多个装饰器装饰同一个函数
def wrapper1(func): def inner(): print('wrapper1 ,before func') func() print('wrapper1 ,after func') return inner def wrapper2(func): def inner(): print('wrapper2 ,before func') func() print('wrapper2 ,after func') return inner @wrapper2 @wrapper1 def f(): print('in f') f() #wrapper2 ,before func #wrapper1 ,before func #in f #wrapper1 ,after func #wrapper2 ,after func - 
class Test(object): def __init__(self, func): print('test init') print('func name is %s ' % func.__name__) self.__func = func def __call__(self, *args, **kwargs): print('装饰器中的功能') self.__func() @Test def test(): print('this is test func') test() #test init #func name is test #装饰器中的功能 #this is test func 
                    
                
                
            
        
浙公网安备 33010602011771号