编辑:为了深入了解装饰师的心理模型,请看看这个很棒的Pycon Talk。这30分钟很值得。
考虑带参数的装饰器的一种方式是
@decorator
def foo(*args, **kwargs):
pass
翻译为
foo = decorator(foo)
如果decorator有参数,
@decorator_with_args(arg)
def foo(*args, **kwargs):
pass
翻译为
foo = decorator_with_args(arg)(foo)
Decorator_with_args是一个函数,它接受自定义参数并返回实际的装饰器(将应用于被装饰的函数)。
我使用了一个简单的技巧与部分,使我的装饰容易
from functools import partial
def _pseudo_decor(fun, argument):
def ret_fun(*args, **kwargs):
#do stuff here, for eg.
print ("decorator arg is %s" % str(argument))
return fun(*args, **kwargs)
return ret_fun
real_decorator = partial(_pseudo_decor, argument=arg)
@real_decorator
def foo(*args, **kwargs):
pass
更新:
上面,foo变成了real_decorator(foo)
修饰函数的一个效果是,foo的名字在修饰器声明中被重写。Foo被real_decorator返回的任何东西“覆盖”。在本例中,是一个新的函数对象。
foo的所有元数据都会被重写,尤其是文档字符串和函数名。
>>> print(foo)
<function _pseudo_decor.<locals>.ret_fun at 0x10666a2f0>
functools。Wraps为我们提供了一个方便的方法,将文档字符串和名称“提升”到返回的函数中。
from functools import partial, wraps
def _pseudo_decor(fun, argument):
# magic sauce to lift the name and doc of the function
@wraps(fun)
def ret_fun(*args, **kwargs):
# pre function execution stuff here, for eg.
print("decorator argument is %s" % str(argument))
returned_value = fun(*args, **kwargs)
# post execution stuff here, for eg.
print("returned value is %s" % returned_value)
return returned_value
return ret_fun
real_decorator1 = partial(_pseudo_decor, argument="some_arg")
real_decorator2 = partial(_pseudo_decor, argument="some_other_arg")
@real_decorator1
def bar(*args, **kwargs):
pass
>>> print(bar)
<function __main__.bar(*args, **kwargs)>
>>> bar(1,2,3, k="v", x="z")
decorator argument is some_arg
returned value is None