Python:如何动态调用具有各种签名的方法

时间:2012-05-20 09:36:36

标签: python

我正在用Python编写测试自动化工具。该工具的一个关键特性是通过具有各种签名的名称来调用方法,就像C#反射一样。然而,在阅读了大量文章并进行了多次测试之后,我找不到处理各种签名的方法。

这是我的第一个想法 -

def invoke(obj, method_name, *args):
    print type(args)
    method = getattr(obj, method_name)
    method(*args)

import sys
module = sys.modules[__name__]
invoke(module, 'foo', 1, 2) 

确实有效。但问题是,名称调用的方法可以有不同数量的参数。然后我认为参数列表可以由元组重新表示,因为args的类型是一个元组。所以我改变了最后一行代码 -

invoke(module, 'foo', (1, 2)) # pass parameter list using a tuple (1, 2)

但是口译员告诉我这个 -

Traceback (most recent call last):
  File "\Src\studies\dynamic_method_call.py", line 14, in <module>
    invoke(module, 'foo', (1, 2))
  File "\Src\studies\dynamic_method_call.py", line 9, in invoke
    print method(*args)
TypeError: foo() takes exactly 2 arguments (1 given)

我也尝试过list和keywored args。他们都没有工作。请指教!

2 个答案:

答案 0 :(得分:5)

为了将一组值的“解包”作为函数调用的参数,只需使用*,例如:

invoke(module, 'foo', *(1, 2))

答案 1 :(得分:1)

invoke(module, 'foo', (1, 2))扩展为foo((1, 2)),因此args((1, 2),)。用一个参数调用foo,而不是两个,因此你的错误。

使用:

def invoke(obj, method_name, *args):
    method = getattr(obj, method_name)
    method(*args)

invoke(module, 'foo', 1, 2)

或者

def invoke(obj, method_name, args):
    method = getattr(obj, method_name)
    method(*args)

invoke(module, 'foo', (1, 2))