我正在尝试访问传递给装饰器中的函数的所有参数,包括可选参数.考虑这个例子:
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)
Run Code Online (Sandbox Code Playgroud)
如果我运行这个,我会得到:
in wrapper (1, 2) {}
in myFn 1 2 None
in wrapper (1, 2, 3) {}
in myFn 1 2 3
Run Code Online (Sandbox Code Playgroud)
在第一次运行中,由于我没有指定3个参数,因此为了myFn,arg3被定义为None.但是在arg3 == None装饰者里面没有的事实,无论是在args还是kwargs.如果我明确地将它传递给myFn,它将显示在装饰器内部,但如果我使用默认值,则无处可寻.
为什么是这样?它怎么能修复?
这很正常,无法"修复"......
装饰器包装器拦截传递给函数的参数和关键字:换句话说,由函数调用者传递给函数本身的参数和关键字.
arg3=None是在函数范围定义的默认参数.在实际调用函数之前(直接或通过包装器),它不能被截获,因为它在那时不存在.
但是,默认值存储在函数对象中:
def fn(arg1,arg2,arg3=None):
pass
fn.func_defaults
-> (None,)
Run Code Online (Sandbox Code Playgroud)
并且您可以使用以下获取函数参数的默认值?将默认值映射到参数...所以我想装饰器可能会花费极长的时间来打印传递和默认的参数.所以我想我的第一个声明并非100%正确:)