首页 > 编程语言 > 详细

Python中的迭代器、生成器、装饰器

时间:2020-02-19 22:47:00      阅读:60      评论:0      收藏:0      [点我收藏+]

1. 迭代器 

 

 1 """
 2     iterator
 3     迭代器协议: 对象必须提供一个next()方法,执行该方法要么返回迭代中的下一项,要么引起一个StopIteration异常,以终止迭代
 4     可迭代对象: 实现可迭代协议的对象。(对象内部定义一个__iter__()方法)
 5     访问方式:下标方式、迭代器协议、for循环
 6 """
 7 
 8 
 9 li = [1, 2, 3, 4, 5]
10 iter_li = li.__iter__()  # 通过__iter__()方法生成可迭代对象
11 print(iter_li)  # <list_iterator object at 0x000002565B5BD748>
12 # print(li[0])
13 print(iter_li.__next__())  # 1
14 print(next(iter_li))  # 2
15 
16 # for 循环访问遵循迭代器访问方式
17 # for i in li:
18 #     print(i)

2. 生成器

 1 """
 2     generator
 3     生成器函数: 定义函数,包换关键字 yield
 4     生成器表达式: 三元表达式
 5     send()
 6 """
 7 
 8 
 9 # 生成器函数
10 def generator_func():
11     yield 1
12     yield 2
13     yield louis
14     yield scar
15     yield rose
16     x = yield
17     print(x=, x)
18     y = yield
19     print(y=, y)
20 
21 
22 gen = generator_func()
23 print(gen)  # <generator object generator_func at 0x000001A5464A2F48>
24 print(gen.__next__())
25 print(gen.__next__())
26 print(gen.__next__())
27 print(gen.__next__())
28 print(gen.__next__())
29 print(gen.__next__())  # None
30 # 改变x的值并触发 __next()__
31 res = gen.send(init_)
32 print(res)  # x= init_ None
33 
34 # 生成器表达式
35 count1 = [x for x in range(10)]  # 列表表达式
36 print(count1)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
37 count2 = (x for x in range(10) if x > 5)  # 生成器表达式
38 print(count2)  # <generator object <genexpr> at 0x000001E364E87840>
39 print(list(count2))  # [6, 7, 8, 9]
40 
41 
42 import time
43 
44 
45 # 生产者消费者模型
46 def consumer(name):
47     print(消费者[%s]开始下单 % name)
48     while True:
49         num = yield
50         time.sleep(0.5)
51         print(%s 第[%s]杯奶茶 % (name, num))
52 
53 
54 def producer():
55     c1 = consumer(louis)
56     c2 = consumer(scar)
57     next(c1)
58     next(c2)
59     for i in range(1, 10):
60         c1.send(i)
61         c2.send(i)
62 
63 
64 producer()

运行结果:
消费者[louis]开始下单
消费者[scar]开始下单
louis 第[1]杯奶茶
scar 第[1]杯奶茶
louis 第[2]杯奶茶
scar 第[2]杯奶茶
louis 第[3]杯奶茶
scar 第[3]杯奶茶
louis 第[4]杯奶茶
scar 第[4]杯奶茶
louis 第[5]杯奶茶
scar 第[5]杯奶茶
louis 第[6]杯奶茶
scar 第[6]杯奶茶
louis 第[7]杯奶茶
scar 第[7]杯奶茶
louis 第[8]杯奶茶
scar 第[8]杯奶茶
louis 第[9]杯奶茶
scar 第[9]杯奶茶

3 装饰器

  a. 装饰器实现日志操作(带参以及不带参的装饰器函数)

 1 """
 2     装饰器:本质就是函数,功能就是为其它函数添加附加功能
 3     使用场景: 插入日志、性能测试、事务处理、缓存、权限校验等
 4     语法糖: @def_func(func)
 5     装饰器 = 高阶函数 + 函数嵌套 + 闭包
 6     高阶函数: 函数的接受的参数是一个函数,返回值也是一个函数
 7     函数嵌套: 在函数里面执行其它函数
 8     闭包: 主要看作用域范围
 9 """
10 import functools
11 
12 
13 def func_logging(arg):
14     print(arg)
15     if callable(arg):  # 如果装饰器不带参数
16         # @functools.wraps(arg)
17         def _deco(*args, **kwargs):
18             print(%s is running % arg.__name__)
19             arg(*args, **kwargs)
20         return _deco
21     else:  # 如果装饰器带参数
22         def _deco(func):
23             @functools.wraps(func)
24             def __deco(*args, **kwargs):
25                 if arg == warn:
26                     print(warn %s is running % func.__name__)
27                 return func(*args, **kwargs)
28             return __deco
29         return _deco
30 
31 
32 @func_logging  # test1 = func_logging(test)
33 def test1():
34     print(this is test1)
35     print(test1.__name__)
36 
37 
38 @func_logging(warn)  # 直接执行 func_logging() 返回装饰器函数 _deco()
39 def test2():
40     print(this is test2)
41     print(test2.__name__)
42 
43 
44 test1()
45 # <function test1 at 0x000002335B5A1EA0>
46 # test1 is running
47 # this is test1
48 # test1
49 # 函数名变为_deco而不是test1,这个情况在使用反射的特性的时候就会造成问题。因此引入了functools.wraps解决这个问题
50 test2()
51 # warn
52 # warn test2 is running
53 # this is test2
54 # test2

  b. 性能测试

 1 import time
 2 import functools
 3 # 性能测试
 4 def timer(func):
 5     @functools.wraps(func)
 6     def warpper(*args, **kwargs):
 7         print(%s is start running % func.__name__)
 8         start_time = time.time()
 9         func(*args, **kwargs)
10         stop_time = time.time()
11         print(%s is stop running, cost %s s % (func.__name__, stop_time - start_time))
12     return warpper
13 
14 
15 @timer
16 def test3():
17     time.sleep(1.0)
18     print(test3.__name__)
19 
20 
21 test3()
22 # test3 is start running
23 # test3
24 # test3 is stop running, cost 1.0015299320220947 s

 

Python中的迭代器、生成器、装饰器

原文:https://www.cnblogs.com/louiszh/p/12333404.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!