装饰器可以在不修改原有代码的基础上添加新的功能,可以将重复重用的代码抽取出来,进一步解耦,方便维护,一般适用于插入日志、性能测试、事务处理、缓存等
一般来说,当一个函数嵌套另一个函数时,内部函数引用到了外部函数的变量,则形成了闭包,如下所示,outter与inner形成了闭包
def outter():
n = 1
def inner():
print(n)
return n
return inner()
print(outter())
1.内部函数可以访问外部函数的变量
2.将外层变量持久化到内存中(一般来说,函数内部的局部变量在这个函数运行完以后,就会被Python的垃圾回收机制从内存中清除掉)
def outter(func):
def inner(*args, **kwargs):
'''inner'''
print('inner start')
return func(*args, **kwargs)
return inner
@outter
def decorator():
'''decorator'''
print('decorator')
decorator()
print(decorator.__name__)
print(decorator.__doc__)
由此结果发现,当添加装饰器后会改变原有函数的__name__及__doc__属性,为此我们需要纠正回来
使用functools下的wraps转译
from functools import wraps
def outter(func):
@wraps(func)
def inner(*args, **kwargs):
'''inner'''
print('inner start')
return func(*args, **kwargs)
return inner
@outter
def decorator():
'''decorator'''
print('decorator')
decorator()
print(decorator.__name__)
print(decorator.__doc__)
需要在外层再包装一个函数,传入需要传递的参数即可,传入的参数也可以用于内部逻辑代码的处理
from functools import wraps
def decorator(name):
def outter(func):
@wraps(func)
def inner(*args, **kwargs):
'''inner'''
print(f'name:{name}')
print('inner start')
return func(*args, **kwargs)
return inner
return outter
@decorator(name='test')
def test():
print('test')
test()
类装饰器不携带参数,只需构造方法传入方法,重写__call__方法即可
class Decorator():
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print('Decorator start')
self.func(*args, **kwargs)
print('Decorator finish')
@Decorator
def test():
print('test')
test()
对于携带参数的类装饰器,构造方法需要为参数, 需要重写__call__方法且需要添加内部函数并返回,__call__方法传入方法,内部函数传递被装饰的函数的参数
class Decorator():
def __init__(self, name):
self.name = name
def __call__(self, func):
def inner(*args, **kwargs):
print('inner start')
print(self.name)
func(*args, **kwargs)
print('inner finish')
return inner
@Decorator(name='test')
def test():
print('test')
test()
手机扫一扫
移动阅读更方便
你可能感兴趣的文章