版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/deng1456694385/article/details/87554463
python-装饰器
在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator).我的理解是为某个已定义的函数增加某些功能,但是不修改函数原始的定义. 有点类似于面向对象的接口实现,装饰器就相当于接口,下面具体的函数是对该接口的实现. 而装饰器的本质就是一个高阶函数,传入的是需要被装饰的函数.
用法
# demo.py
def printFuncName(func):
def wrapper(*args, **kw):
print(func.__name__)
return func(*args, **kw)
return wrapper
@printFunName
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
#调用
>>> from demo import person
>>> person(1,2)
person
name: 1 age: 2 other: {}
上面的printFuncName
就是一个装饰器,就是在person
被调用前,对函数进行改造,func
就是函数体,(*args,**kw)
就是传入函数的参数,所以func.__name__
就是函数得到名字person
,装饰器的作用等同于:
person = printFuncName(person)
但是这样出现了一个问题
>>> person.__name__
'wrapper'
因为person
内部真正的函数名以及变成了wrapper
了,这时候我们可以用Python内置的装饰器functools.wraps
来将wrapper
的属性和原来函数的属性统一
#demo.py
import functools
def printName(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print(func.__name__)
return func(*args, **kw)
return wrapper
@printName
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
#调用
>>> from demo import person
>>> person.__name__
'person'
如果你需要动态的装饰器,就需要给装饰器传入参数了,所以你需要在原本的装饰器外层在嵌套一层用于传入参数创建一个装饰器的函数,这才是最完整的装饰器
#demo.py
import functools
def printName(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s:%s' % (text, func.__name__)) #正则的写法
return func(*args, **kw)
return wrapper
return decorator
@printName('函数的名字')
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
#调用
>>> from demo import person
>>> person(1,2)
函数的名字:person
name: 1 age: 2 other: {}