python装饰器
参考:廖雪峰python教程
函数装饰器
函数装饰器:给函数添加功能,举例如下:
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log
def now():
print('2015-3-25')
now()
# 输出:
# call now():
# 2015-3-25
把@log
放到now()
函数的定义处,相当于执行了语句:
now = log(now)
所以now实际上已经是wrapper函数,调用now就是wrapper函数。在wrapper函数中首先打印了日志,然后调用了旧版的now函数并返回旧版的now的返回值。在这里log的作用是返回包装好的函数对象wrapper。
此时函数now的名字变为了wrapper,如下:
>>> now.__name__
'wrapper'
修改log函数,让名字变回now:
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
Python内置的functools.wraps
执行wrapper.__name__ = func.__name__
这样的代码,让名字变回now。
带参数的函数装饰器
如果log需要传入参数,那么代码修改如下:
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
@log('execute')
def now():
print('2015-3-25')
执行:
>>> now()
execute now():
2015-3-25
和两层嵌套的装饰器相比,3层嵌套的效果是这样的:
>>> now = log('execute')(now)
和两层嵌套的装饰器相比,都是返回包装好的wrapper函数对象。
用python装饰器修饰类
作用:给类添加一个函数。
def add_method(cls):
def print_hello(self):
print("Hello")
cls.print_hello = print_hello
return cls
@add_method
class MyClass:
pass
obj = MyClass()
obj.print_hello() # 输出 "Hello"
在上面的示例中,我们定义了一个名为 add_method 的装饰器函数,它接受一个类作为参数,并将一个名为 print_hello 的方法添加到该类中。然后我们使用 @add_method 装饰器将 MyClass 类传递给 add_method 函数,这样我们就在 MyClass 中添加了一个新的方法 print_hello。最后,我们实例化 MyClass 类,并调用 print_hello 方法来输出 "Hello"。