【发布时间】:2018-07-14 23:22:17
【问题描述】:
我有一个装饰器来注册一些类方法。如何正确获取self 和run 参数?
Traceback(最近一次调用最后一次):
TypeError: wrapper() got multiple values for keyword argument 'run'
【问题讨论】:
-
您的代码没有您描述的错误。 (假设
from functools import *)
我有一个装饰器来注册一些类方法。如何正确获取self 和run 参数?
Traceback(最近一次调用最后一次):
TypeError: wrapper() got multiple values for keyword argument 'run'
【问题讨论】:
from functools import *)
您的问题与装饰器无关。以更简单的形式:您正在做的是:
def foo(run=False, *args, **kwargs):
print(run, args, kwargs)
foo(1, 2, run=True) # TypeError: foo() got multiple values for argument 'run'
根据您的函数签名,python 将尝试设置run=1、args = (2,),然后运行到TypeError。
一个修复 - 虽然不是一个很好的 - 可能是:
def foo(*args, **kwargs):
run = kwargs.pop('run', False) # run defaults to False; remove from kwargs
print(run, args, kwargs)
【讨论】:
foo 作为你的wrapper 函数。更改其签名并从kwargs 获取run。这实际上是the other answer 已经详细建议的内容......
run参数来自fun,所以尝试从函数的参数中获取:
from collections import defaultdict
from copy import deepcopy
from functools import wraps
class Task(object):
_tasks = []
@staticmethod
def register(name):
def decorator(fn):
@wraps(fn)
def wrapper(self=None, *args, **kwargs):
run = kwargs.pop('run', True)
if not run:
task = defaultdict()
task['name'] = name
task['fn'] = getattr(self, fn.__name__, None)
task['obj'] = self
task['args'] = deepcopy(args)
task['kwargs'] = deepcopy(kwargs)
Task._tasks.append(task)
else:
return fn(self, *args, **kwargs)
return wrapper
return decorator
【讨论】:
Python3 似乎有更好的参数处理程序,但不知道如何在 python2 中执行此操作:
从 functools 导入包装 def optional_debug(func): @wraps(函数) def 包装器(*args,debug=False,**kwargs): 如果调试: print('调用', func.__name__) 返回函数(*args,**kwargs) 返回包装 @optional_debug 定义垃圾邮件(a,b,c): 打印(a,b,c) 垃圾邮件(1,2,3)#1,2,3 spam(1,2,3, debug=True) # 调用垃圾邮件 # 1 2 3【讨论】: