Python中类似于Ruby obj.send的方法是什么?

13

在 Ruby 中,如果我有一个名为 obj 的对象,它有一个名为 funcname 的方法,我可以使用以下语法调用该方法:

obj.send(funcname)

在 Python 中是否有类似的东西呢?

我想这么做的原因是,我有一个带有 switch 语句的函数,在其中设置了 funcname,而且希望在 switch 语句结束时调用它。


2
Python没有switch语句。此外,在运行时生成函数名称几乎总是一个不好的主意。 - Rafe Kettler
2
@Rafe:这并不是常见的需求,但它本身并没有什么邪恶之处。 - Glenn Maynard
是的,它不行,但我仍然想在if-elif-else循环中实现它。我认为我在下面得到了答案。 - Puneet Paul
你可以随时将函数赋值为:"f = obj.func",然后稍后调用f(args)。当需要时,Python的方法绑定非常有用。 - Glenn Maynard
4个回答

26
getattr(obj, "name")(args)

​​​​


10

嗯... getattr(obj, funcname)(*args, **kwargs)?

>>> s = "Abc"

>>> s.upper()
'ABC'

>>> getattr(s, "upper")()
'ABC'

>>> getattr(s, "lower")()
'abc'

1
除了已经提到的getattr()内置函数之外:
作为if-elif-else循环的替代方案,您可以使用字典将您的“情况”映射到所需的函数/方法:
# given func_a, func_b and func_default already defined
function_dict = {
    'a': func_a,
    'b': func_b  
}
x = 'a'
function_dict(x)() # -> func_a()
function_dict.get('xyzzy', func_default)() # fallback to -> func_c

关于方法而非普通函数:

  • 可以使用lambda obj: obj.method_a()代替function_a等,将上述示例转换为method_dict,然后执行method_dict[case](obj)
  • 如其他答案所述,可以使用getattr(),但只有在确实需要通过名称获取方法时才需要它。
  • stdlib中的operator.methodcaller()是某些情况下的一个不错的快捷方式:基于方法名称和可选参数,它创建一个函数,在另一个对象上调用该名称的方法(如果您在创建methodcaller时提供了任何额外的参数,则会使用这些参数调用该方法)。

1
或者,如果你喜欢,operator.methodcaller('foo') 是一个函数,它在你传递给它的任何对象上调用 foo。换句话说,
import operator
fooer = operator.methodcaller("foo")
fooer(bar)

等同于

bar.foo()

(如果您倾向于数学)我认为这可能是合适范畴中的伴随或对偶。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接