一:闭包
闭包概念:
在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包。
个人理解就是:内部函数调用外部函数的变量,参数等,外部函数返回的是内部函数
1 def set(number): 2 print("---------外部函数输出-----------") 3 def get(): 4 print("-------------内部函数----------") 5 a = number+100 6 print(a) 7 return get 8 9 >>> b = set(100) 10 ---------外部函数输出----------- 11 >>> b() 12 -------------内部函数---------- 13 200
上述例子就是一个闭包,b其实就是相当于是get()函数(或者说b就是指向get()),然后b()就相当于在调用get()函数。其实如果内部函数get()带有参数,那么可以b(参数)。
二:装饰器
例1:
1 def test(fn): 2 def test1(): 3 print('-----11------') 4 5 return test1 6 @test 7 def fn(): 8 print('-----222-------') 9 fn()
运行结果:
1 -----11------
例2:
1 def test(fn): 2 def test1(): 3 print('-----11------') 4 fn() 5 return test1 6 @test 7 def fn(): 8 print('-----222-------') 9 fn()
运行结果:
1 -----11------ 2 -----222-------
个人理解装饰器:就是闭包写一个额外的功能,然后在不用在原基础代码中添加代码,其中靠@实现(也称语法糖)
上述例子中:
在fn()就函数上加上@test 就相当于执行以下三步:
1:调用test()函数,
2:把fn()函数当做参数传入test()函数中,然后返回test1()函数对象,
3:然后调用test1()函数。
注意:如果在test1()函数中 没用调用fn函数,那么结果只会输出test1()函数中的结果;如果调用,则会先返回test1()函数中的结果,然后再返回fn()函数中的。
例3:
1 def makeBlod(fn): 2 def wrapped(): 3 return "<b>"+fn()+"</b>" 4 return wrapped 5 6 >>> @makeBlod 7 def test(): 8 return "xxx是一个大傻子" 9 10 >>> test() 11 '<b>xxx是一个大傻子</b>'
注意:在闭包模式的内部函数中调用test()函数,没有必要非要写test()调用,只要和参数一致即可。
3:有参数的函数使用装饰器
1 def test(fn): 2 def test1(a,b): 3 print('-----11------') 4 fn(a,b) 5 return test1 6 @test 7 def fn(a,b): 8 c = a + b 9 print('-----222-------') 10 print(c) 11 fn(10,11)
运行结果:
1 -----11------ 2 -----222------- 3 21
注意:就是当调用的函数带有参数时,则需要在闭包中的内部函数带上参数,内部函数中调用的函数也需要带上参数
3.1:当参数不定长时
def test(fn): def test1(*args,**kwargs): print('-----11------') fn(*args,**kwargs) return test1 @test def fn(a,b,c): print('-----222-------') d=a+b+c print(d) fn(5,6,7)
运行结果:
1 -----11------ 2 -----222------- 3 18
4:对带有返回值的函数进行装饰器装饰
1 def test(fn): 2 def test1(): 3 print('-----11------') 4 xxx = fn() 5 return xxx 6 return test1 7 @test 8 def fn(): 9 print('-----222-------') 10 return '我是带有返回值的函数' 11 12 a = fn() 13 print(a)
运行结果:
-----11------
-----222-------
我是带有返回值的函数
注意:对带有返回值的函数使用装饰器进行装饰的时候,需要在内部函数中调用的时候,用xxx接收,然后返回
5:带有参数的装饰器
1 def f_arg(arg): 2 def test(fn): 3 def test1(): 4 print('-----11------') 5 fn() 6 return test1 7 d=arg+10 8 print(d) 9 return test 10 @f_arg(10) 11 def fn(): 12 print('-----222-------') 13 fn()
运行结果:
1 20 2 -----11------ 3 -----222-------
理解:@f_arg(10)就是
1:先执行f_arg(arg)函数,这个函数的return的结果就是test这个函数的引用
2:@test
3:使用@test对fn()函数进行装饰
以上是个人理解,2018-03-22