1

当您使用错误数量的参数或使用不在其定义中的关键字参数调用函数时,您会收到 TypeError。我想要一段代码来获取回调并根据回调支持的内容使用可变参数调用它。一种方法是,对于回调cb,使用cb.__code__.cb_argcountand cb.__code__.co_varnames,但我宁愿将其抽象为类似的东西apply,但这仅适用于“适合”的参数。

例如:

 def foo(x,y,z):
   pass

 cleanvoke(foo, 1)         # should call foo(1, None, None)
 cleanvoke(foo, y=2)       # should call foo(None, 2, None)
 cleanvoke(foo, 1,2,3,4,5) # should call foo(1, 2, 3)
                           # etc.

Python中是否已经有类似的东西,还是我应该从头开始编写?

4

2 回答 2

7

与其自己深入研究细节,不如检查函数的签名——你可能想要inspect.getargspec(cb).

您究竟想如何使用该信息以及您拥有的参数来“正确”调用该函数,我并不完全清楚。假设为简单起见,您只关心简单的命名参数,并且您想要传递的值在 dict d...

args = inspect.getargspec(cb)[0]
cb( **dict((a,d.get(a)) for a in args) )

也许你想要一些更高级的东西,并且可以详细说明什么?

于 2009-06-01T03:47:31.073 回答
3

这也许?

def fnVariableArgLength(*args, **kwargs):
    """
    - args is a list of non keywords arguments
    - kwargs is a dict of keywords arguments (keyword, arg) pairs
    """
    print args, kwargs


fnVariableArgLength() # () {}
fnVariableArgLength(1, 2, 3) # (1, 2, 3) {}
fnVariableArgLength(foo='bar') # () {'foo': 'bar'}
fnVariableArgLength(1, 2, 3, foo='bar') # (1, 2, 3) {'foo': 'bar'}

编辑 您的用例

def foo(*args,*kw):
    x= kw.get('x',None if len(args) < 1 else args[0])
    y= kw.get('y',None if len(args) < 2 else args[1])
    z= kw.get('z',None if len(args) < 3 else args[2])
    # the rest of foo

foo(1)         # should call foo(1, None, None)
foo(y=2)       # should call foo(None, 2, None)
foo(1,2,3,4,5) # should call foo(1, 2, 3)
于 2009-06-01T03:57:23.490 回答