使用函数的名字从一个string中调用一个模块的函数

在Python程序中调用给函数名string的函数的最好方法是什么? 例如,假设我有一个模块foo ,并且我有一个string,其内容是"bar" 。 什么是最好的方式去调用foo.bar()

我需要获得函数的返回值,这就是为什么我不使用eval 。 我想通过使用eval来定义一个返回该函数调用的结果的临时函数,但我希望有一个更优雅的方式来做到这一点。

假设模块foo与方法bar

 import foo method_to_call = getattr(foo, 'bar') result = method_to_call() 

就此而言,第2行和第3行可以压缩到:

 result = getattr(foo, 'bar')() 

如果这对你的用例更有意义。 您可以以这种方式在类实例绑定方法,模块级方法,类方法上使用getattr …列表继续。

 locals()["myfunction"]() 

要么

 globals()["myfunction"]() 

当地人用当前的本地符号表返回一个字典。 全局variables返回带有全局符号表的字典。

帕特里克的解决scheme可能是最干净的。 如果您还需要dynamic获取模块,可以像下面这样导入它:

 module = __import__('foo') func = getattr(module, 'bar') func() 

只是一个简单的贡献。 如果我们需要实例的类在同一个文件中,我们可以使用像这样的东西:

 # Get class from globals and create an instance m = globals()['our_class']() # Get the function (from the instance) that we need to call func = getattr(m, 'function_name') # Call it func() 

例如:

 class A: def __init__(self): pass def sampleFunc(self, arg): print('you called sampleFunc({})'.format(arg)) m = globals()['A']() func = getattr(m, 'sampleFunc') func('sample arg') # Sample, all on one line getattr(globals()['A'](), 'sampleFunc')('sample arg') 

而且,如果不是class级:

 def sampleFunc(arg): print('you called sampleFunc({})'.format(arg)) globals()['sampleFunc']('sample arg') 

给定一个string,一个完整的Python函数path,这是我如何得到所述函数的结果:

 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就像行为

 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")() 

对于什么是值得的,如果你需要传递函数(或类)名称和应用程序名称作为一个string,那么你可以这样做:

 myFnName = "MyFn" myAppName = "MyApp" app = sys.modules[myAppName] fn = getattr(app,myFnName) 

根据Python编程常见问题的最佳答案是:

 functions = {'myfoo': foo.bar} mystring = 'myfoo' if mystring in functions: functions[mystring]() 

这种技术的主要优点是string不需要匹配函数的名字。 这也是用来模拟案例结构的主要技术

没有任何build议帮助了我。 我确实发现了这一点。

 <object>.__getattribute__(<string name>)(<params>) 

我使用Python 2.66

希望这可以帮助

尝试这个。 虽然这仍然使用eval,但它只是用它从当前上下文中调用函数 。 那么,你有真正的function使用,如你所愿。

对我来说,主要的好处是你可以在召唤这个函数的时候得到任何与eval有关的错误。 那么当你打电话时,你只会得到与function有关的错误。

 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)