LaVOZs

The World’s Largest Online Community for Developers

'; python - Calling a function of a module by using its name (a string) - LavOzs.Com

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 content is "bar". What is the best way to call 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.

Assuming module foo with method bar:

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

You could shorten lines 2 and 3 to:

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.

locals()["myfunction"]()

or

globals()["myfunction"]()

locals returns a dictionary with a current local symbol table. globals returns a dictionary with global symbol table.

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

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')

Given a string, with a complete python path to a function, this is how I went about getting the result of said function:

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

The best answer according to the Python programming FAQ would be:

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

The answer (I hope) no one ever wanted

Eval like behavior

getattr(locals().get("foo") or globals().get("foo"), "bar")()

Why not add 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")()

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)

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.

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)

none of what was suggested helped me. I did discover this though.

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

I am using python 2.66

Hope this helps

As this question How to dynamically call methods within a class using method-name assignment to a variable [duplicate] marked as a duplicate as this one, I am posting a related answer here:

The scenario is, a method in a class want to call another method on the same class dynamically, I have added some details to original example which offers some wider scenario and clarity:

class MyClass:
    def __init__(self, i):
        self.i = i

    def get(self):
        func = getattr(MyClass, 'function{}'.format(self.i))
        func(self, 12)   # This one will work
        # self.func(12)    # But this does NOT work.


    def function1(self, p1):
        print('function1: {}'.format(p1))
        # do other stuff

    def function2(self, p1):
        print('function2: {}'.format(p1))
        # do other stuff


if __name__ == "__main__":
    class1 = MyClass(1)
    class1.get()
    class2 = MyClass(2)
    class2.get()

Output (Python 3.7.x)

function1: 12

function2: 12

This is a simple answer, this will allow you to clear the screen for example. There are two examples below, with eval and exec, that will print 0 at the top after cleaning (if you're using Windows, change clear to cls, Linux and Mac users leave as is for example) or just execute it, respectively.

eval("os.system(\"clear\")")
exec("os.system(\"clear\")")
Related
Calling an external command from Python
How to import a module given its name as string?
How do I check if a string is a number (float)?
Using global variables in a function
Converting string into datetime
How to make a chain of function decorators?
Does Python have a string 'contains' substring method?
Determine function name from within that function (without using traceback)
Creating a singleton in Python