参考博客: https://www.cnblogs.com/Lin-Yi/p/7306235.html
函数装饰器用于在源码中标记函数, 以某种方式增强函数的行为。 装饰器会在加载模块时直接运行。
装饰器是可调用的对象, 其参数是被装饰的函数。 但装饰器通常会把函数替换位另一个函数
实现一个简单的装饰器:
def decorate(func):
def inner():
print("我是装饰器")
func()
return inner
@decorate
def func():
pass
func()
print(func)
我是装饰器
<function decorate.<locals>.inner at 0x000002B0C71D5378>
闭包是指延申了作用域的函数。
自由变量(free variable) 指未在本地作用域中绑定的变量 python中使用nonlocal来标记自由变量
如果被装饰的函数带参数:
def decorate(func):
def inner(*args):
print("开始装饰")
func(*args)
print("装饰结束")
return inner
@decorate
def func(*args):
print(*args)
func(1, 2) # 由于装饰器会把被装饰的函数替换为另一个函数,这里是inner,所以在定义inner函数时接收参受
开始装饰
1 2
装饰结束
如果目标函数需要多层装饰:
def decorate1(func):
def inner(*args, **kwargs):
print("装饰器1开始装饰")
func(*args, **kwargs)
print("装饰器1装饰结束")
return inner
def decorate2(func):
def inner(*args, **kwargs):
print("装饰器2开始装饰")
func(*args, **kwargs)
print("装饰器2装饰结束")
return inner
@decorate1 # 相当于 func = decorate1(decorate2(func)) 先执行decrate1() 函数 decorate1函数中的func执行也就是 decorate2(func)开始执行。
@decorate2
def func(*args):
print(*args)
func(1, 2)
装饰器1开始装饰
装饰器2开始装饰
1 2
装饰器2装饰结束
装饰器1装饰结束
可选择装饰器, 需要三层闭包嵌套:
def flagoperation(flag):
def decorate(func):
def inner(*args, **kwargs):
print("装饰器开始装饰")
func(*args, **kwargs)
if flag == True:
print("我是后置操作")
print("装饰器装饰结束")
return inner
return decorate
@flagoperation(True) # 相当于 decorate(func) 带着一个参数 True 带着True参数再对目标函数进行装饰
def func(*args):
print(*args)
func(1, 2)
装饰器开始装饰
1 2
我是后置操作
装饰器装饰结束