参考:https://www.zhihu.com/question/26930016
不影响函数本身的执行功能,在函数执行的时候额外做一些其他的事情:
pythonimport logging
def use_logging(func): # 传入函数对象
def wrapper(*args, **kwargs):
logging.warning("%s is running k" % func.__name__) # 做一些装饰器的工作
return func(*args, **kwargs) # 返回函数对象执行结果
return wrapper # 返回函数
def bar():
print("i am bar")
bar = use_logging(bar) # 返回的是一个函数对象
bar()
通过@语法糖,装饰器可以很漂亮地给函数用上,增加程序的可读性:
pythonimport logging
def use_logging(func): # 传入函数对象
def wrapper(*args, **kwargs):
logging.warning("%s is running k" % func.__name__) # 做一些装饰器的工作
return func(*args, **kwargs) # 返回函数对象执行结果
return wrapper # 返回函数
@use_logging
def bar():
print("i am bar")
@use_logging
def foo():
print("i am foo")
bar()
对原有参数再包装了一次:
pythonimport logging
def use_logging(level): # 传入函数对象
def decorator(func):
def wrapper(*args, **kwargs):
if level == "warning":
logging.warning("%s is running k" % func.__name__) # 做一些装饰器的工作
return func(*args, **kwargs) # 返回函数对象执行结果
return wrapper
return decorator # 返回函数
@use_logging(level="warning")
def bar():
print("i am bar")
bar()
pythonclass Foo():
def __init__(self, func):
self._func = func
def __call__(self, *args, **kwargs):
print("class decorator running")
self._func()
print("class decorator end")
@Foo
def bar():
print("i am bar")
bar()
在之前的装饰器,为函数装上了装饰器后函数的元信息丢失(如__name__
),functools.wraps可以让装饰器不改变函数的元信息。
pythonfrom functools import wraps
def logged(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("was called")
return func(*args, **kwargs) # 返回函数对象执行结果
return wrapper # 返回函数
@logged
def bar():
print("i am bar")
return "HHHH"
print(bar.__name__)
print(bar())
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!