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) 收藏 举报
浙公网安备 33010602011771号