python学习 生成器/迭代器/闭包/装饰器

 1 '''生成器:为了减少内存占用,创建一个计算方法,只有在调用时才会执行'''
 2 #列表生成式:
 3 a=[i*2 for i in range(10)]
 4 print(a) #打印结果:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
 5 
 6 #创建生成器方法一:
 7 b=(i*2 for i in range(10))
 8 print(b)  #打印结果:<generator object <genexpr> at 0x00000231523E2B88>
 9 print(next(b)) #打印结果:0
10 print(next(b)) #打印结果:2
11 print(next(b)) #打印结果:4
12 
13 #创建生成器方法二 yield :
14 #斐波那契数列指的是这样一个数列1、1、2、3、5、8、13、21、34、……这个数列从第3项开始,每一项都等于前两项之和
15 def fib():
16     a,b=0,1
17     for i in range(5):
18         # print(b) #打印结果:1、1、2、3、5
19         yield b
20         a,b=b,a+b
21 
22 #创建了一个生成器对象
23 a=fib()
24 #调用方法一:
25 print(a)  #打印结果:<generator object fib at 0x0000025E91382B88>
26 print(next(a))   #打印结果:1
27 print(next(a))   #打印结果:1
28 print(next(a))   #打印结果:2
29 print(next(a))   #打印结果:3
30 print(next(a))   #打印结果:5
31 
32 #调用方法二:
33 for i in a:
34     print(i)
35 
36 #调用方法三:
37 for i in range(5):
38     # print(next(a)) #等价于print(a.__next__())
39     print(a.__next__())
40 
41 #生成器-send传一个值
42 def test():
43     i=0
44     while i<5:
45         num=yield i
46         print(num)
47         i+=1
48 
49 a=test()
50 print(a.__next__())     #打印结果:0
51 print(a.send('hehe'))  #打印结果:hehe 1
52 print(a.__next__())     #打印结果:None 2
53 print(a.send('a'))  #打印结果:a 3
54 print(a.__next__())     #打印结果:None 4
55 
56 def test1():
57     i=0
58     while i<5:
59         if i==0:
60             temp=yield i
61             print(temp)
62         else:
63             yield i
64         i+=1
65 
66 a=test1()
67 print(a.send(None))  #打印结果:0
68 print(a.send('hh'))  #打印结果:hh 1
69 print(a.__next__())  #打印结果:2
70 print(a.__next__())  #打印结果:3
71 
72 #使用yield完成多任务 ---相当于协程
73 def a1():
74     while True:
75         print('---1---')
76         yield None
77 
78 def a2():
79     while True:
80         print('---2---')
81         yield None
82 
83 a1=a1()
84 a2=a2()
85 while True:
86     a1.__next__()
87     a2.__next__()
生成器

 

 1 '''迭代器'''
 2 #迭代是访问集合元素的一种方法。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问为止。迭代器只能往前不会后退
 3 
 4 #可迭代对象(Iterable)-有[],{},(),str,字典,列表生成式/器,这些可以直接作用于for循环的对象统称为可迭代对象
 5 #判断是否是可迭代对象
 6 from collections.abc import Iterable
 7 print(isinstance([],Iterable))  #True
 8 print(isinstance((i for i in range(5)),Iterable)) #True
 9 print(isinstance((),Iterable))  #True
10 print(isinstance({},Iterable))  #True
11 print(isinstance('',Iterable))  #True
12 print(isinstance(10,Iterable))  #False
13 
14 '''可迭代器(Iterator)-可以被next()函数调用并不断返回下一个值的对象成为迭代器
15 生成器一定是迭代器,但迭代器不一定是生成器'''
16 # #判断是否是迭代器
17 from collections.abc import Iterator
18 print(isinstance((i for i in range(5)),Iterator))  #生成器 True
19 print(isinstance([i for i in range(5)],Iterator))  #False
20 print(isinstance([],Iterator))  #False
21 print(isinstance((),Iterator))  #False
22 print(isinstance({},Iterator))  #False
23 print(isinstance('',Iterator))  #False
24 print(isinstance(10,Iterator))  #False
25 
26 #创建迭代器-iter()函数
27 #生成器都是Iterator对象,但[],{},(),str,字典虽然是Iterable,却不是Iterator。
28 #把[],{},(),str,字典等Iterable变成Iterator(),可以使用iter()函数
29 a=[1,2,3,4,5]
30 b=iter(a)
31 print(b) #<list_iterator object at 0x00000157D19B66A0>
32 print(b.__next__())  #打印结果 1
33 print(b.__next__())  #打印结果 2
迭代器

 

 1 '''闭包'''
 2 def test(num):
 3     print(num)
 4     #在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
 5     def test_in(number_in):
 6         print(number_in)
 7         return num+number_in
 8     #其实这里返回的就是闭包的结果
 9     print('hhhhh')
10     return test_in
11 
12 a=test(100)  #打印结果  100 hhhhh
13 print(a(10))  #打印结果  10 110
14 print(a(20))  #打印结果  20 120
15 
16 #闭包的实际应用--简化代码调用方式,传参少了
17 def test(a,b):
18     def test_in(x):
19         print(x*a,b)
20     return test_in
21 
22 line1=test(1,1)
23 line1(0) #打印结果 0 1
24 
25 line2=test(1,2)
26 line2(2)  #打印结果 2 2
闭包

 

  1 '''装饰器'''
  2 #-----装饰器原理-----
  3 def w1(func):
  4     def inner():
  5         print('---正在验证权限---')
  6         func()
  7     return inner
  8 
  9 def f1():
 10     print('--f1--')
 11 
 12 def f2():
 13     print('--f2')
 14 
 15 # a=w1(f1)
 16 # a()
 17 # b=w1(f2)
 18 # b()
 19 
 20 f1()
 21 f1=w1(f1)  #这里相当于重新定义了f1()函数
 22 f1()
 23 
 24 #----装饰器运用----
 25 def w1(func):
 26     def inner():
 27         print('---正在验证权限---')
 28         func()
 29     return inner
 30 
 31 @w1    #等价于f1=w1(f1)
 32 def f1():
 33     print('--f1--')
 34 
 35 @w1    #等价于f2=w1(f2)
 36 def f2():
 37     print('--f2')
 38 
 39 f1()
 40 f2()
 41 
 42 #------两个装饰器-----
 43 def testa(fn):
 44     def linea():
 45         print('--1--')
 46         return '<b>'+fn()+'<b>'
 47     return linea
 48 
 49 def testb(fn):
 50     def lineb():
 51         print('--2--')
 52         return '<i>'+fn()+'<i>'
 53     return lineb
 54 
 55 #只有python解释器执行到了这个代码,那么就会自动的进行装饰,而不是等到调用的时候才装饰
 56 @testa
 57 @testb   #当有多个装饰器时,是从下再往上装的。但是执行顺序还是从上往下的
 58 def fn():
 59     print('--3--')
 60     return 'hello world'
 61 
 62 #在调用fn之前,已经进行装饰了
 63 res=fn()
 64 print(res)
 65 
 66 ####打印结果:
 67 # --1--
 68 # --2--
 69 # --3--
 70 # <b><i>hello world<i><b>
 71 
 72 #-----装饰器对有参数的函数进行装饰----
 73 def func(functionName):
 74     print('func')
 75     def func_in(*args,**kwargs):
 76         functionName(*args,**kwargs)
 77     return func_in
 78 
 79 @func
 80 def test1(a,b):
 81     print('test1,{}-{}'.format(a,b))
 82 
 83 @func
 84 def test2(a,b,c):
 85     print('test2,{}-{}-{}'.format(a,b,c))
 86 
 87 test1(1,2)
 88 test2(3,4,5)
 89 
 90 # ####打印结果:
 91 # func
 92 # func
 93 # test1,1-2
 94 # test2,3-4-5
 95 
 96 #------------装饰器对带有返回值的函数进行装饰--------------
 97 def fun(functionName):
 98     def func_in():
 99         aa=functionName() #保存返回来的hh
100         return aa  #把hh返回到函数的调用
101     return func_in
102 
103 @fun
104 def test():
105     print('test')
106     return 'hh'
107 
108 a=test()
109 print('result-{}'.format(a))
110 
111 #------------通用装饰器--------------
112 def fun(functionName):
113     def func_in(*args,**kwargs):
114         print('日志打印')
115         aa=functionName(*args,**kwargs)
116         return aa
117     return func_in
118 
119 @fun
120 def test():
121     print('test')
122     return 'hh'
123 
124 @fun
125 def test1():
126     print('test1')
127 
128 @fun
129 def test2(aa):
130     print('test2-{}'.format(aa))
131 
132 a=test()
133 print('result-{}'.format(a))
134 test1()
135 test2('aaa')
136 
137 #------------带有参数的装饰器--------------
138 #带有参数的装饰器,能够起到在运行时,有不同的功能
139 def fun_arg(a1):
140     def fun(functionName):
141         def func_in(*args,**kwargs):
142             print('日志打印:{}'.format(a1))
143             if a1=='哈哈':
144                 functionName(*args,**kwargs)
145                 functionName(*args,**kwargs)
146             else:
147                 functionName(*args, **kwargs)
148         return func_in
149     return fun
150 
151 #1、先执行fun_arg('哈哈')函数,这个函数return的结果是fun这个函数的引用
152 #2、@func
153 #3、使用@func对test1进行装饰
154 @fun_arg('哈哈')
155 def test1():
156     print('test1')
157 
158 @fun_arg('嘻嘻')
159 def test2():
160     print('test2')
161 
162 test1()
163 test2()
装饰器

 

 1 #------------通用装饰器--------------
 2 import functools
 3 def fun(functionName):
 4     @functools.wraps(functionName)   ## 保证被装饰的函数对象的__name__不变
 5     def func_in(*args,**kwargs):
 6         print('日志打印')
 7         aa=functionName(*args,**kwargs)
 8         return aa
 9     return func_in
10 
11 @fun
12 def a():
13     print('test')
14     return 'hh'
15 
16 @fun
17 def a1():
18     print('test1')
19 
20 @fun
21 def a2(aa):
22     print('test2-{}'.format(aa))
23 
24 a=a()
25 print(a1.__name__)  #不加@functools.wraps(functionName),打印结果是func_in。加了后,打印结果是a1
26 # print('result-{}'.format(a))
27 # a1()
28 # a2('aaa')
装饰器-补充

 

 1 #__call__()方法返回的是一个函数的引用
 2 class Test():
 3     def __init__(self):
 4         print('hhh')
 5 
 6     def __call__(self, *args, **kwargs):
 7         print('aaaa')
 8 
 9 a=Test()
10 a() #__call__()方法起的作用
11 
12 #类装饰器
13 class Test():
14     def __init__(self,fun):
15         print('hhh')
16         fun()
17         self.__fun=fun
18 
19     def __call__(self, *args, **kwargs):
20         print('aaaa')
21         self.__fun()
22 
23 @Test
24 def test():
25     print('--test--')
26 
27 test()
28 
29 #打印结果
30 # hhh
31 # --test--
32 # aaaa
33 # --test--
类装饰器

 

posted on 2019-08-06 20:41  cherry_ning  阅读(139)  评论(0)    收藏  举报

导航