1、闭包
1.1、定义
嵌套定义函数,但是我们实际应用中用的是内部函数,通过return返回内部函数的地址
def func(a,b):
def callback(x):
print(a*x+b)
return callback
a= func(1,2)
a(4)
闭包和函数的区别:
函数只有代码。
闭包除了代码之外还有他独有的数据
2、装饰器
大致原理:将要装饰的对象的函数名传给闭包的才不函数,然后在内部函数调用被装饰的函数,最后将外部函数的返回值赋给要被装饰的函数名
示例:
def set_func(func):
def callback():
print("新增功能")
func()
return callback
def test():
print("原产品")
test = set_func(test)
test()
最后用@set_fun代替test = set_func(test)
即如下:
def set_func(func):
def callback():
print("新增功能")
func()
return callback
@set_func #写了该句话就代表在下面的位置加了一句test = set_func(test)
def test():
print("原产品")
#test = set_func(test)
test()
装饰器作用:
增加新功能
3、给有参数的函数添加装饰器
def set_func(func):
def call_back(a,b):
print("新功能1")
func(a,b)
print("新功能2")
return call_back
@set_func
def test(a,b):
print(a+b)
test(1,2)
4、给有不定长参数的函数添加装饰器
def set_func(func):
def call_back(*args,**kwargs):
print("新功能1")
func(*args,**kwargs) #解包,
print("新功能2")
return call_back
@set_func
def test(a,*args,**kwargs):
print(a)
print(args,kwargs)
test(1,2,4,k=3)
5、给有返回值不定长参数的函数添加装饰器(通用版)
def set_func(func):
def call_back(*args,**kwargs):
print("新功能1")
ret = func(*args,**kwargs) #解包,
print("新功能2")
return ret
return call_back
@set_func
def test(a,*args,**kwargs):
print(a)
print(args,kwargs)
return "ok"
test(1,2,4,k=3)
6、多给装饰器给一个函数装饰
def set_func1(func):
print("装饰器1\n")
def call_back(*args,**kwargs):
print("新功能1")
ret = func(*args,**kwargs) #解包,
#print("新功能2")
return ret
return call_back
def set_func2(func):
print("装饰器2\n")
def call_back(*args,**kwargs):
print("新功能3")
ret = func(*args,**kwargs) #解包,
#print("新功能4")
return ret
return call_back
@set_func1
@set_func2
def test(a,*args,**kwargs):
print(a)
print(args,kwargs)
return "ok"
test(1,2,4,k=3)
运行结果:
装饰器2
装饰器1
新功能1
新功能3
1
(2, 4) {'k': 3}
'ok'
结论:装饰时由下到上,执行时由上到下
7、一个装饰给多个函数装饰
def set_level(level_num):
def set_func(func):
def call_back(*args,**kwargs):
print("新功能1")
if level_num == 1:
print("这是权限1")
elif level_num == 2:
print("这是权限1")
else:
pass
#ret = func(*args,**kwargs) #解包,
print("新功能2")
return func(*args,**kwargs)
return call_back
return set_func
@set_level(1)
def test1(a,*args,**kwargs):
print("test1")
print(a)
print(args,kwargs)
return "ok1"
@set_level(2)
def test2(a,*args,**kwargs):
print("test2")
print(a)
print(args,kwargs)
return "ok2"
print(test1(1,2,4,k=3))
print(test2(1,2,4,k=3))
结果:
新功能1
这是权限1
新功能2
test1
1
(2, 4) {'k': 3}
ok1
新功能1
这是权限1
新功能2
test2
1
(2, 4) {'k': 3}
ok2
8、带有参数的装饰器
def set_level(level_num):
def set_func(func):
def call_back(*args,**kwargs):
print("新功能1")
if level_num == 1:
print("这是权限1")
elif level_num == 2:
print("这是权限2")
else:
pass
#ret = func(*args,**kwargs) #解包,
print("新功能2")
return func(*args,**kwargs)
return call_back
return set_func # 下面的装饰过程
# 1. 调用set_level(1)
# 2. 将步骤1得到的返回值,即set_func返回, 然后set_func(test1)
# 3. 将set_func(test1)的结果返回,即call_back
# 4. 让test1 = call_back,即test1现在指向call_back
@set_level(1)
def test1(a,*args,**kwargs):
print("test1")
print(a)
print(args,kwargs)
return "ok1"
@set_level(2)
def test2(a,*args,**kwargs):
print("test2")
print(a)
print(args,kwargs)
return "ok2"
print(test1(1,2,4,k=3))
print(test2(1,2,4,k=3))
结果
新功能1
这是权限1
新功能2
test1
1
(2, 4) {'k': 3}
ok1
新功能1
这是权限2
新功能2
test2
1
(2, 4) {'k': 3}
ok2
带参数的装饰器应用增加权限验证