【发布时间】:2019-12-13 17:38:04
【问题描述】:
我有一个装饰器,我想在那个装饰器中检查被装饰的函数是否有一个名为 query 的参数。如果它存在,我想像这样检测它在*args 中的位置:args[1]。我想在包装函数中执行此操作。我想做这样的事情:
def some_decorator(func):
@wraps(func)
def wrapper_func(*args, **kwargs):
ind = 0
query = ''
for arg in args:
if arg.__name__ == 'query'
query = 'Found'
break
ind +=1
if query == 'Found':
query = args[ind]
return wrapper_func
为了清楚起见,我这样使用它:
@some_decorator
def find_all(self, some_arg, query=None):
pass
问题是,我也将装饰器用于其他功能,具有不同的签名,可能有也可能没有query 参数。我希望这能澄清一些事情。
【问题讨论】:
-
我认为你做不到。
*args仅包含值。没有办法知道名字。如果您需要知道名称,请使用**kwargs。 -
@JohnGordon,...getting method parameter names in python 的可接受/有效答案的存在似乎与该声明相矛盾。
-
@CharlesDuffy 我认为这个问题提出了完全不同的问题。它问“如果我有一个函数的引用,我如何确定它的参数名称?”即如果我有一个函数
def foo(arg1, arg2),我怎么能在运行时知道它的参数被命名为arg1和arg2?但我对 this 问题的解释是,它需要 caller's 上下文中的 args 名称,即如果我调用foo(x, y),foo 如何确定传递的参数是x和y?不能。 -
好吧,“不能”不做一些真正怪诞(而且可能是正确的)的事情,比如走到调用者的堆栈框架并检查其本地人以找到匹配的人,或者尝试分析它的AST 并希望它只对手头的函数进行一次调用。但我认为问题中没有任何依据,即 OP 正在寻找的是调用者上下文中的名称,而不是被调用函数上下文中的名称。
-
@EzizDurdyyev, ...所以,如果你想最终解决我与 JohnGordon 的争论,不仅要展示你是如何使用装饰器,而且你是如何调用修饰函数的。你会期望
foo.find_all(baz, qux)触发qux,因为它在查询位置被传递(正如我所料,在这种情况下 GCG 的答案是响应式的),或者因为调用者没有给它命名@而被忽略987654338@ 在它的上下文中(我理解约翰将你解释为所要求的)。
标签: python