What is the best way to go about calling a function given a string with the function's name in a Python program. For example, let's say that I have a module foo
, and I have a string whose contents are "bar"
. What is the best way to go about calling foo.bar()
?
在Python程序中,使用函数的名称调用函数的最佳方法是什么?例如,假设我有一个模块foo,并且我有一个字符串,它的内容是“bar”。关于调用foo.bar()的最好方法是什么?
I need to get the return value of the function, which is why I don't just use eval
. I figured out how to do it by using eval
to define a temp function that returns the result of that function call, but I'm hoping that there is a more elegant way to do this.
我需要得到函数的返回值,这就是为什么我不只是使用eval。我已经知道如何使用eval来定义一个temp函数,它返回函数调用的结果,但是我希望有一个更优雅的方法来实现它。
10 个解决方案
#1
1347
Assuming module foo
with method bar
:
假设模块foo与方法栏:
import foo
method_to_call = getattr(foo, 'bar')
result = method_to_call()
As far as that goes, lines 2 and 3 can be compressed to:
就这一点而言,第2行和第3行可以压缩为:
result = getattr(foo, 'bar')()
if that makes more sense for your use case. You can use getattr
in this fashion on class instance bound methods, module-level methods, class methods... the list goes on.
如果这对您的用例更有意义。您可以在类实例绑定方法、模块级方法、类方法中使用getattr。的例子不胜枚举。
#2
#3
219
Patrick's solution is probably the cleanest. If you need to dynamically pick up the module as well, you can import it like:
帕特里克的解决方案可能是最干净的。如果您需要动态地获取模块,您可以导入它:
module = __import__('foo')
func = getattr(module, 'bar')
func()
#4
75
Just a simple contribution. If the class that we need to instance is in the same file, we can use something like this:
只是一个简单的贡献。如果我们需要实例的类在同一个文件中,我们可以使用如下的方法:
# 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()
For example:
例如:
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')
And, if not a class:
如果不是一个类:
def sampleFunc(arg):
print('you called sampleFunc({})'.format(arg))
globals()['sampleFunc']('sample arg')
#5
63
Given a string, with a complete python path to a function, this is how I went about getting the result of said function:
给定一个字符串,在一个函数中有一个完整的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()
#6
30
The answer (I hope) no one ever wanted
答案(我希望)没有人想要。
Eval like behavior
Eval等行为
getattr(locals().get("foo") or globals().get("foo"), "bar")()
Why not add auto-importing
为什么不添加auto-importing
getattr(
locals().get("foo") or
globals().get("foo") or
__import__("foo"),
"bar")()
In case we have extra dictionaries we want to check
如果我们有多余的词典,我们想查一下。
getattr(next((x for x in (f("foo") for f in
[locals().get, globals().get,
self.__dict__.get, __import__])
if x)),
"bar")()
We need to go deeper
我们需要更进一步。
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")()
#7
25
The best answer according to the Python programming FAQ would be:
根据Python编程FAQ,最好的答案是:
functions = {'myfoo': foo.bar}
mystring = 'myfoo'
if mystring in functions:
functions[mystring]()
The primary advantage of this technique is that the strings do not need to match the names of the functions. This is also the primary technique used to emulate a case construct
这种技术的主要优点是字符串不需要匹配函数的名称。这也是用于模拟案例构造的主要技术。
#8
18
For what it's worth, if you needed to pass the function (or class) name and app name as a string, then you could do this:
如果需要将函数(或类)名称和应用程序名称作为字符串传递,那么您可以这样做:
myFnName = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn = getattr(app,myFnName)
#9
14
Try this. While this still uses eval, it only uses it to summon the function from the current context. Then, you have the real function to use as you wish.
试试这个。虽然这仍然使用eval,但它只使用它从当前上下文调用函数。然后,你就有了你想要的功能。
The main benefit for me from this is that you will get any eval-related errors at the point of summoning the function. Then you will get only the function-related errors when you call.
我的主要好处是,在调用函数时,您将得到任何与事件相关的错误。然后在调用时只会得到与功能相关的错误。
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)
#10
12
none of what was suggested helped me. I did discover this though.
建议对我没有帮助。我确实发现了这个。
<object>.__getattribute__(<string name>)(<params>)
I am using python 2.66
我使用的是python 2.66。
Hope this helps
希望这有助于
#1
1347
Assuming module foo
with method bar
:
假设模块foo与方法栏:
import foo
method_to_call = getattr(foo, 'bar')
result = method_to_call()
As far as that goes, lines 2 and 3 can be compressed to:
就这一点而言,第2行和第3行可以压缩为:
result = getattr(foo, 'bar')()
if that makes more sense for your use case. You can use getattr
in this fashion on class instance bound methods, module-level methods, class methods... the list goes on.
如果这对您的用例更有意义。您可以在类实例绑定方法、模块级方法、类方法中使用getattr。的例子不胜枚举。
#2
376
locals()["myfunction"]()
or
或
globals()["myfunction"]()
locals returns a dictionary with a current local symbol table. globals returns a dictionary with global symbol table.
当地人用当前本地符号表返回字典。globals返回一个带有全局符号表的字典。
#3
219
Patrick's solution is probably the cleanest. If you need to dynamically pick up the module as well, you can import it like:
帕特里克的解决方案可能是最干净的。如果您需要动态地获取模块,您可以导入它:
module = __import__('foo')
func = getattr(module, 'bar')
func()
#4
75
Just a simple contribution. If the class that we need to instance is in the same file, we can use something like this:
只是一个简单的贡献。如果我们需要实例的类在同一个文件中,我们可以使用如下的方法:
# 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()
For example:
例如:
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')
And, if not a class:
如果不是一个类:
def sampleFunc(arg):
print('you called sampleFunc({})'.format(arg))
globals()['sampleFunc']('sample arg')
#5
63
Given a string, with a complete python path to a function, this is how I went about getting the result of said function:
给定一个字符串,在一个函数中有一个完整的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()
#6
30
The answer (I hope) no one ever wanted
答案(我希望)没有人想要。
Eval like behavior
Eval等行为
getattr(locals().get("foo") or globals().get("foo"), "bar")()
Why not add auto-importing
为什么不添加auto-importing
getattr(
locals().get("foo") or
globals().get("foo") or
__import__("foo"),
"bar")()
In case we have extra dictionaries we want to check
如果我们有多余的词典,我们想查一下。
getattr(next((x for x in (f("foo") for f in
[locals().get, globals().get,
self.__dict__.get, __import__])
if x)),
"bar")()
We need to go deeper
我们需要更进一步。
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")()
#7
25
The best answer according to the Python programming FAQ would be:
根据Python编程FAQ,最好的答案是:
functions = {'myfoo': foo.bar}
mystring = 'myfoo'
if mystring in functions:
functions[mystring]()
The primary advantage of this technique is that the strings do not need to match the names of the functions. This is also the primary technique used to emulate a case construct
这种技术的主要优点是字符串不需要匹配函数的名称。这也是用于模拟案例构造的主要技术。
#8
18
For what it's worth, if you needed to pass the function (or class) name and app name as a string, then you could do this:
如果需要将函数(或类)名称和应用程序名称作为字符串传递,那么您可以这样做:
myFnName = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn = getattr(app,myFnName)
#9
14
Try this. While this still uses eval, it only uses it to summon the function from the current context. Then, you have the real function to use as you wish.
试试这个。虽然这仍然使用eval,但它只使用它从当前上下文调用函数。然后,你就有了你想要的功能。
The main benefit for me from this is that you will get any eval-related errors at the point of summoning the function. Then you will get only the function-related errors when you call.
我的主要好处是,在调用函数时,您将得到任何与事件相关的错误。然后在调用时只会得到与功能相关的错误。
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)
#10
12
none of what was suggested helped me. I did discover this though.
建议对我没有帮助。我确实发现了这个。
<object>.__getattribute__(<string name>)(<params>)
I am using python 2.66
我使用的是python 2.66。
Hope this helps
希望这有助于