如何使用带有函数名称的字符串调用函数?例如:
import foo
func_name = "bar"
call(foo, func_name) # calls foo.bar()
如何使用带有函数名称的字符串调用函数?例如:
import foo
func_name = "bar"
call(foo, func_name) # calls foo.bar()
当前回答
还没有人提到operator.attrgetter:
>>> from operator import attrgetter
>>> l = [1, 2, 3]
>>> attrgetter('reverse')(l)()
>>> l
[3, 2, 1]
>>>
其他回答
答案(我希望)从来没有人想要
Eval样行为
getattr(locals().get("foo") or globals().get("foo"), "bar")()
为什么不添加自动导入
getattr(
locals().get("foo") or
globals().get("foo") or
__import__("foo"),
"bar")()
万一我们有多余的字典要查
getattr(next((x for x in (f("foo") for f in
[locals().get, globals().get,
self.__dict__.get, __import__])
if x)),
"bar")()
我们需要更深入
getattr(next((x for x in (f("foo") for f in
([locals().get, globals().get, self.__dict__.get] +
[d.get for d in (list(dd.values()) for dd in
[locals(),globals(),self.__dict__]
if isinstance(dd,dict))
if isinstance(d,dict)] +
[__import__]))
if x)),
"bar")()
给定一个字符串和一个函数的完整python路径,这就是我如何获得所述函数的结果:
import importlib
function_string = 'mypackage.mymodule.myfunc'
mod_name, func_name = function_string.rsplit('.',1)
mod = importlib.import_module(mod_name)
func = getattr(mod, func_name)
result = func()
试试这个。虽然这仍然使用eval,但它只使用它从当前上下文调用函数。然后,您就可以随心所欲地使用真正的函数了。
这对我的主要好处是,在调用函数时,您将得到任何与eval相关的错误。然后,当您调用时,只会得到与函数相关的错误。
def say_hello(name):
print 'Hello {}!'.format(name)
# get the function by name
method_name = 'say_hello'
method = eval(method_name)
# call it like a regular function later
args = ['friend']
kwargs = {}
method(*args, **kwargs)
基于Patrick的解决方案,要动态获取模块,请使用以下方法导入:
module = __import__('foo')
func = getattr(module, 'bar')
func()
getattr根据对象的名称调用方法。但此对象应该是调用类的父对象。父类可以由super(self.__class__,self)获取
class Base:
def call_base(func):
"""This does not work"""
def new_func(self, *args, **kwargs):
name = func.__name__
getattr(super(self.__class__, self), name)(*args, **kwargs)
return new_func
def f(self, *args):
print(f"BASE method invoked.")
def g(self, *args):
print(f"BASE method invoked.")
class Inherit(Base):
@Base.call_base
def f(self, *args):
"""function body will be ignored by the decorator."""
pass
@Base.call_base
def g(self, *args):
"""function body will be ignored by the decorator."""
pass
Inherit().f() # The goal is to print "BASE method invoked."