1. 装饰器简介
装饰器其实是一种闭包,装饰器是闭包的一种应用,其功能就是在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能。
2. 装饰器
1. 一般写法(闭包写法)
def expand(func):
'''
工作函数
:param func:
:return:
'''
def wrapper():
print("开始工作了...")
func()
print("工作完成,下班了...")
return wrapper
def work():
print("工作中...")
fn = expand(work)
fn()
执行结果如下:
在上面这个例子中,我们定义了一个闭包函数wrapper
,在闭包函数内部,在执行目标函数的前后分别增加两个功能,“开始工作"和"工作完成,下班了”。
2. 语法糖写法
def expand(func):
'''
工作函数
:param func:
:return:
'''
def wrapper():
print("开始工作了...")
func()
print("工作完成,下班了...")
return wrapper
@expand
def work():
print("工作中...")
work()
执行结果如下:
在上面这个例子中,目标函数work
前加上@expand
,在不修改代码的情况下,增加了两个功能,“开始工作"和"工作完成,下班了”。
3. 带参数的装饰器
def out(out_args):
def expand(func):
'''
工作函数
:param func:
:return:
'''
def wrapper(*args, **kwargs):
print("这个例子是:", out_args)
print("开始工作了...")
func(*args, **kwargs)
print("工作完成,下班了...")
return func
return wrapper
return expand
@out(out_args="带参数的装饰器")
def work(name):
print("{}正在工作中...".format(name))
work("猪小明")
使用带有参数的装饰器,其实是在装饰器外面又包裹了一个函数,使用该函数接收参数,返回是装饰器,因为 @
符号需要配合装饰器实例使用。
4. 类装饰器
4.1 一般写法
class expand():
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("开始工作了...")
self.func(*args, **kwargs)
print("工作完成,下班了...")
return self.func
@expand
def work(name):
print("{}正在工作中...".format(name))
使用类装饰器,用法与函数装饰器差不多,实际上是使用了类中的call魔法方法来实现类的直接调用。
4.2 带参数的类装饰器
class expand():
def __init__(self, out_args):
self.out_args = out_args
def __call__(self, func):
def wrapper(*args, **kwargs):
print("这个例子是:", self.out_args)
print("开始工作了...")
func(*args, **kwargs)
print("工作完成,下班了...")
return func
return wrapper
@expand(out_args="带参数的装饰器")
def work(name):
print("{}正在工作中...".format(name))
work("猪小明")
使用类的带参数装饰器和带参数的函数装饰器类似,类中的call方和带参数的函数装饰器内层装饰器对应,类中init方法和带参数的函数装饰器最外层接收参数的函数对应。
如上就是装饰器的一些概念和简单例子,想要更深入理解还需要更多的练习。