你能判断这是否总是最后一个参数吗?如果没有,您将不得不使用它的名称。
我的想法是这样做:
def check_orc(orc):
if isinstance(orc, int):
orc = str(orc)
print DeprecationWarning("You should not be sending snaga to combat")
return orc
def check_opp(meth):
code = meth.func_code
argnames = code.co_varnames[:code.co_argcount]
if 'opponent' in argnames:
from functools import wraps
argidx = argnames.index('opponent')
@wraps(meth)
def replace(*a, **k):
if 'opponent' in k:
k['opponent'] = check_orc(k['opponent'])
else:
a = list(a)
a[argidx] = check_orc(a[argidx])
a = tuple(a)
return meth(*a, **k)
return replace
else:
return meth
class Warrior():
@check_opp
def slash_orc(self, sword, shield, opponent):
print "slash", (sword, shield, opponent)
@check_opp
def hack_orc(self, warhammer, opponent):
print "hack", (warhammer, opponent)
Warrior().slash_orc(1,3,4)
Warrior().hack_orc(6,5)
Warrior().slash_orc(1,3,opponent=4)
Warrior().hack_orc(6,opponent=5)
Warrior().slash_orc(1,3,"4")
Warrior().hack_orc(6,"5")
Warrior().slash_orc(1,3,opponent="4")
Warrior().hack_orc(6,opponent="5")
这是一个非常丑陋的 hack,但仍然可以工作,并且可以避免重新排序参数。
在这里,我使用一种检查来找到正确的参数并对其进行修改,无论它是作为关键字还是索引参数传递。
请注意,我稍微更改了测试以使其适合我(我“弃用”整数并需要 strs)。您只需要我的check_opp()
功能并将其应用到您需要的任何地方。