Python之挖掘迭代器、生成器、装饰器三代祖坟

一、迭代器

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)这件事情
原文地址:https://www.cnblogs.com/Alexephor/p/11197765.html