27

我正在使用 getattr 根据变量调用不同的函数。

我正在做这样的事情:

getattr(foo, bar) ()

这行得通,调用像 foo.bar() 这样的函数

我的问题是我有'bar'函数,我想用不同的参数调用它。例如:

def f1() :
  pass

def f2(param1) :
  pass

def f3(param1,param2) :
  pass

所以“bar”可以是 f1、f2 或 f3

我试过这个:假设 params 是一个列表,其中包含“bar”函数所需的所有参数

getattr(foo, bar) (for p in params :)

我正在寻找一个“干净”的解决方案,无需查看 params 变量的长度

4

3 回答 3

36

您可以尝试以下方法:

getattr(foo, bar)(*params)

如果params是列表或元组,则此方法有效。from 中的元素params将按顺序解包:

params=(1, 2)
foo(*params)

相当于:

params=(1, 2)
foo(params[0], params[1])

如果有关键字参数,您也可以这样做。

getattr(foo, bar)(*params, **keyword_params)

keyword_params字典在哪里。

此外,这个答案真的独立于getattr. 它适用于任何功能/方法。

于 2012-08-02T15:53:47.650 回答
5

这在 Python 3 中非常简单。下面是示例:

class C:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def m(self, x):
        print(f"{self.name} called with param '{x}'")
        return

ci = C("Joe", 10)
print(C)
print(ci)
print(C.m)
print(ci.m)
print(getattr(ci,'m'))
getattr(ci,'m')('arg')

<class '__main__.C'>
<__main__.C object at 0x000001AF4025FF28>
<function C.m at 0x000001AF40272598>
<bound method C.m of <__main__.C object at 0x000001AF4025FF28>>
<bound method C.m of <__main__.C object at 0x000001AF4025FF28>>
Joe called with param 'arg'

请注意,getattr来自内置模块,在我们的例子中接受两个参数,类实例ci和表示函数名称的字符串。

我们还可以定义参数的默认值。

def m(self, x=None):
    print(f"{self.name} caled with param '{x}'")
    return

在这种情况下,我们可以调用:

getattr(ci,'m')()
于 2019-05-24T14:16:16.970 回答
1

一种可能更易读的方式,更适合处理异常:

class foo:
    def method_xy(self, *args, **kwargs):
        print(f'args:{args}, kwargs:{kwargs}')


bar = 'method_xy'
xi = foo()
try:
    func_name = getattr(xi, bar)
except AttributeError:
    # handle missing method
    pass

args = ['bla1', 'bla2']
kwargs = {'a1': 1, 'a2': 2}

try:
    result = func_name(*args, **kwargs)
except TypeError:
    # handle Problems with arguments
    pass
于 2020-01-22T15:53:16.573 回答