Python 访问decorator中的可选参数
我正在尝试访问传递给decorator中函数的所有参数,包括可选参数。考虑这个例子:Python 访问decorator中的可选参数,python,decorator,Python,Decorator,我正在尝试访问传递给decorator中函数的所有参数,包括可选参数。考虑这个例子: def decorator(fn): def wrapper(*args, **kwargs): print 'in wrapper', args, kwargs fn(*args, **kwargs) return wrapper @decorator def myFn(arg1, arg2, arg3=None): print 'in myFn',
def decorator(fn):
def wrapper(*args, **kwargs):
print 'in wrapper', args, kwargs
fn(*args, **kwargs)
return wrapper
@decorator
def myFn(arg1, arg2, arg3=None):
print 'in myFn', arg1, arg2, arg3
myFn(1,2)
myFn(1,2,3)
如果我运行这个,我将得到:
in wrapper (1, 2) {}
in myFn 1 2 None
in wrapper (1, 2, 3) {}
in myFn 1 2 3
在第一次运行中,由于我没有指定3个参数,因此出于myFn的目的,arg3被定义为None。但是,arg3==None
这一事实在decorator内部不可用,无论是在args还是kwargs中。如果我显式地将它传递给myFn,它将显示在装饰器中,但是如果我使用默认值,它将不存在
为什么会这样?这是很正常的,不能“修复” decorator包装器截取传递给函数的参数和关键字:换句话说,函数调用方传递给函数本身的参数和关键字
arg3=None
是在函数作用域中定义的默认参数。在函数实际被调用(直接调用或通过包装器调用)之前,它不能被拦截,因为此时它不存在
但是,默认值存储在函数对象中:
def fn(arg1,arg2,arg3=None):
pass
fn.func_defaults
-> (None,)
您可以使用以下命令将默认值映射到参数。。。因此,我认为装饰程序可以尽可能地打印传递的和默认的参数。因此,我假设我的第一条语句不是100%正确:)您可以使用包来保留函数签名:
from decorator import decorator
def decorate(f):
def wrapper(f, *args, **kwargs):
print 'in wrapper', args, kwargs
return f(*args, **kwargs)
return decorator(wrapper, f)
@decorate
def myFn(arg1, arg2, arg3=None):
print 'in myFn', arg1, arg2, arg3
myFn(1, 2)
myFn(1, 2, 3)
myFn(1, 2, arg3=10)
输出:
in wrapper (1, 2, None) {}
in myFn 1 2 None
in wrapper (1, 2, 3) {}
in myFn 1 2 3
in wrapper (1, 2, 10) {}
in myFn 1 2 10
基本上,使用
@decorator
语法就像分配myFn=decorator(myFn)
。是的,您设置的arg3=None
在装饰器中并不存在。为什么不使用与myFn
相同的参数定义包装器呢?其最终目标是让装饰程序查找可选参数(纯文本名称)并返回一个id,以便在myFn中使用。但是我希望能够将它应用到大量函数中,这些函数都有不同的调用签名。所以基本上,直到fn本身在包装器中被实际调用,arg3变量才被定义。很好的解释。我想decorator.decorator
达到了我在回答中提到的极限?还是有别的把戏?