TypeError:bar()为关键字参数'_old'获取了多个值
问题描述:
我知道在python中有一个名为decorator
的东西,它可以比下面的代码更干净地完成工作。但我只是好奇为什么下面的代码不起作用。TypeError:bar()为关键字参数'_old'获取了多个值
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def wrap(old, new):
"Override an existing function."
def repl(*args, **kwargs):
return new(_old=old, *args, **kwargs)
return repl
class MyClass(object):
def foo(self, data):
print data
return data
def bar(self, _old, data):
print 'running foo'
_old(data)
print 'foo completed'
MyClass.foo = wrap(MyClass.foo, bar)
mc = MyClass()
mc.foo('Test Data')
当我运行的代码,我得到了一个错误:
Traceback (most recent call last):
File "./test.py", line 24, in <module>
mc.foo('Test Data')
File "./test.py", line 7, in repl
return new(_old=old, *args, **kwargs)
TypeError: bar() got multiple values for keyword argument '_old'
有什么不对吗?我该如何解决它?
答
有几个错误涉及缺少“自我”参数,并且您有关键字参数导致位置参数 - 它必须是相反的。试试这个(Python 3中,还原您认为合适的。):
def wrap(old, new):
"Override an existing function."
return lambda *args, **kwargs: new(*args, _old=old, **kwargs)
class MyClass(object):
def foo(self, data):
print(data)
return data
def bar(self, data, _old):
print('running foo')
_old(self, data)
print('foo completed')
MyClass.foo = wrap(MyClass.foo, bar)
mc = MyClass()
mc.foo('Test Data')
通过移动_old是在的位置参数结束并重新排列的号召,我们希望得到的东西的工作:
> python3 myclass.py
running foo
Test Data
foo completed
>
我相信具体的错误“得到了关键字参数‘_old’由以下引起你调用‘吧’这样多个值:
新(_old =旧,* ARGS,** kwargs)
whic^h被重新安排到:
新(个体经营,数据,_old =旧)
(positionals导致关键字),但如果我们看酒吧的论点:
条(自我,_old,数据)
我们可以看到_old得到了两次,一次作为第二个位置参数,一次作为关键字参数。
部分困惑可能是Python有两个稍微不同但交互的'关键字参数'概念:通过关键字传递的位置参数;未指定的其他参数作为关键字传递。两人都在这里玩。
为什么你的函数'bar'有一个参数'self'? – jacob
问题可能是'自己'那里,也许这个答案在这里可以帮助http://*.com/questions/18950054/class-method-generates-typeerror-got-multiple-values-for-keyword-argument – trainoasis
@jacob因为'wrap'是为了用'bar'来代替'foo'。 'foo'有一个参数'self',所以'bar'应该有'self'参数。 – Searene