一、迭代器
1、迭代器协议 有next方法 一直直到StopIteration终止 (只能往前走不能后退)
2.可迭代对象 遵行迭代器协议的对象就称之为可迭代对象 转换成可迭代对象:iter方法
Python中字符串 列表 元组 字典 集合 文件都不是可迭代对象,但是可以转换成可迭代对象iter
1 l = [1, 2, 3] 2 iter_l = l.__iter__() 3 print(iter_l.__next__()) 4 print(iter_l.__next__()) 5 print(iter_l.__next__()) 6 print(iter_l.__next__()) 7 print(next(iter_l))
二、Python中for循环强大的机制
for运行机制就是
1.iter 2.next 3.捕捉StopIteration
为什么要有for循环
如果说字符串 列表 元组有序的while也可以实现,但是对于无序的类型呢?只有通过for循环当然有序同样能够进行操作
三、生成器(可迭代对象)
1.特征
1.自动实现迭代器协议 不再调用iter方法
2.表现形式 函数式yield 生成器表达式(类似列表推导式)
1 def test(): 2 yield 1 3 yield 2 4 yield 3 5 6 7 g = test() 8 print(g) 9 print(g.__next__()) 10 print(g.__next__()) 11 print(g.__next__())
2.三元表达式、列表解析
1 name = 'eric' 2 res = 'sb' if name == 'eric' else 'shuai' 3 print(res) 4 5 l = [i for i in range(10)] 6 print(l)
1 l = [i for i in range(10) if i > 5] 2 print(l)
生成器 1.比列表解析节省内存牛皮好啊2.函数式的生成器阔以保存函数运行状态
1 l = (i for i in range(10)) 2 print(l.__next__()) 3 print(l.__next__()) 4 print(l.__next__()) 5 print(next(l))
1 print(sum(i*2 for i in range(101)))
四、yield关键字
yield相当于return 控制函数的返回值
x = yield的另外一个特性 接收send传过来的值,赋值给x
1 def test(): 2 print('开始啦') 3 first = yield 1 # return 1 first=None 4 print('第一次', first) 5 yield 2 6 print('第二次') 7 8 9 t = test() 10 res = t.__next__() 11 print(res) 12 res = t.send(None) # send触发生成器下一步运行 13 print(res)
五、基于生成器模拟生产者消费者模型
1 import time 2 3 4 def consumer(name): 5 print('我是%s,我开始准备开始吃包子' % name) 6 while True: 7 baozi = yield 8 time.sleep(1) 9 print('%s 很开心的把%s吃掉了' % (name, baozi)) 10 11 12 def producer(): 13 c1 = consumer('eric') 14 c1.__next__() 15 for i in range(1, 11): 16 time.sleep(1) 17 c1.send('屎馅包子%s' % i) 18 19 20 producer()
杂货
1 # 函数传递参数时 是引用 2 # name = 'eric' 3 # 4 # 5 # def show(): 6 # print(id(name)) 7 # 8 # 9 # print(id(name)) 10 # show()
六、装饰器
本质就是函数,为其它函数添加新的功能
把握两原则:不修改被修饰函数的源代码 不修改被修饰函数的调用方式
装饰器=高阶函数+函数嵌套+闭包
1、高阶函数:传入参数函数名: 为被修饰函数增加功能但是改变了调用方式
返回值函数名:不修改函数的调用的方式
把上边两个方式结合起来就实现装饰器了
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import time 5 6 7 def foo(): 8 time.sleep(1) 9 print('from foo') 10 11 12 def timer(func): 13 """ 14 传入参数函数名 15 :param func: 16 :return: 17 """ 18 start_time = time.time() 19 func() 20 stop_time = time.time() 21 print('函数的运行时间%s' %(stop_time-start_time)) 22 23 24 timer(foo) # 违背函数调用方式 25 26 def timer(func): 27 """ 28 from foo 29 函数运行的时间1.0009970664978027 30 from foo 这样确实能够统计出foo运行的时间,调用方式也没改变 但是多执行一次foo函数 31 :param func: 32 :return: 33 """ 34 start_time = time.time() 35 func() 36 stop_time = time.time() 37 print('函数运行的时间%s' %(stop_time-start_time)) 38 return func 39 40 41 foo = timer(foo) 42 foo()
2、函数嵌套
1 def father(name): 2 # print('from father %s' %name) 3 4 def son(): 5 # print('我的爸爸是%s' %name) 6 7 def grandson(): 8 print('我的爷爷是%s' %name) 9 grandson() 10 son() 11 12 13 father('Mr.Wei')
3、闭包:作用域的一种表现
类的装饰器实现
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 def deco(obj): 6 print(obj) 7 obj.x = 1 8 obj.y = 2 9 return obj 10 11 12 @deco # Foo = deco(Foo) 13 class Foo: 14 pass 15 16 17 @deco 18 def test(): 19 print('test') 20 21 22 print(Foo.__dict__) 23 print(test.__dict__) # 这里也可以说明Python中一切皆对象说明 24 """ 25 <class '__main__.Foo'> 26 <function test at 0x00000235EBFD4A60> 27 {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2} 28 {'x': 1, 'y': 2} 29 """
类的装饰器完善版本
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 def Typed(**kwargs): 6 def deco(obj): 7 for k, v in kwargs.items(): 8 setattr(obj, k, v) 9 return obj 10 return deco 11 12 13 @Typed(x=1, y=2) # Typed(x=1, y=2)---->deco @deco--->Foo = deco(Foo) 14 class Foo: 15 pass 16 17 18 @Typed(name='eric') 19 class Bar: 20 pass 21 22 23 print(Foo.__dict__) 24 print(Bar.__dict__)
函数的装饰器实现
1 def timer(func): # func=test 2 def wrapper(*args, **kwargs): 3 start_time = time.time() 4 res = func(*args, **kwargs) # 在运行test() 5 stop_time = time.time() 6 print('运行的时间%s' %(stop_time-start_time)) 7 return res 8 return wrapper 9 10 11 @timer # test = timer(test) 12 def test(): 13 time.sleep(1) 14 print('test函数运行完毕') 15 16 17 # test = timer(test) # 返回的是wrapper地址 18 # test() # 执行的wrapper函数 19 print(test()) 20 21 # @timer就相当于做了test = timer(test)这件事情