具体来说,当您有一个函数调用另一个函数,但第二个函数的签名未知时。
我知道您可以将 *args 和 **kwargs 用于类似的事情,但我似乎无法以一种始终有效的方式完全正确。
例如,这样的事情几乎可以工作:
class Invoker():
def __init__(self, call):
self._call = call
def call(self, *args, **kwargs):
self._call(*args, **kwargs)
..但是如果我为它写一些测试,我会得到这个输出:
1 -> 2 ('Hello')
1 -> 2 ((3, 'Hello'))
1 -> 2 ('Hello'), ({'left': 'right'})
1 -> 2 ((3,)), ({'value': 'Hello'})
call5() got multiple values for keyword argument 'value'
call5() got multiple values for keyword argument 'value'
从此代码:
# Known argument list: works fine
def call(x, y, value=None):
print("%d -> %d (%r)" % (x, y, value))
invoker = Invoker(call)
invoker.call(1, 2, value="Hello")
# Unknown argument list with no kwargs: works fine
def call2(x, y, *args):
print("%d -> %d (%r)" % (x, y, args))
invoker = Invoker(call2)
invoker.call(1, 2, 3, "Hello")
# Unknown kwargs with default value: works fine
def call3(x, y, value=None, **kwargs):
print("%d -> %d (%r), (%r)" % (x, y, value, kwargs))
invoker = Invoker(call3)
invoker.call(1, 2, value="Hello", left="right")
# Unknown args and kwargs: works fine
def call4(x, y, *args, **kwargs):
print("%d -> %d (%r), (%r)" % (x, y, args, kwargs))
invoker = Invoker(call4)
invoker.call(1, 2, 3, value="Hello")
# Default value with unknown args: fails
try:
def call5(x, y, value=None, *args):
print("%d -> %d (%r), (%r)" % (x, y, value, args))
invoker = Invoker(call5)
invoker.call(1, 2, 3, value="Hello")
except Exception, e:
print(e)
# Default value with unknown args and kwargs: fails
try:
def call6(x, y, value=None, *args, **kwargs):
print("%d -> %d (%r), (%r), (%r)" % (x, y, value, args, kwargs))
invoker = Invoker(call5)
invoker.call(1, 2, 3, value="Hello", left="right")
except Exception, e:
print(e)
当要调用的方法的签名除了在运行时之外未知时,如何编写一个调用另一个始终有效的方法的方法?