By ricree


2008-08-06 03:36:08 8 Comments

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.

11 comments

@Serjik 2019-03-26 18:15:53

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

@Patrick Johnmeyer 2008-08-06 03:57:16

Assuming module foo with method bar:

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:

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.

@Shaun 2014-06-03 13:20:58

hasattr or getattr can be used to determine if a function is defined. I had a database mapping (eventType and handling functionName) and I wanted to make sure I never "forgot" to define an event handler in my python

@Blairg23 2014-06-21 07:39:34

This works if you already know the module name. However, if you want the user to provide the module name as a string, this won't work.

@geekofalltrades 2014-08-16 18:01:37

If you need to avoid a NoneType is not callable exception, you could also employ the three-argument form of getattr: getattr(foo, 'bar', lambda: None). I apologize for the formatting; the stackexchange android app is apparently terrible.

@NuSkooler 2015-06-19 22:19:34

See also the answer provided by @sastanin if you only care for example about your local/current module's functions.

@azmeuk 2015-08-26 23:20:55

This does not work with functions that use a decorator. getattr returns the outer function

@tuned 2015-08-29 17:54:24

Note: cool +1, this made me understand once more that in Python everything is an object. Consequently, it works also with variables, you can access a module's variables as any other object's variables.

@Robert Parcus 2015-11-05 12:38:41

If you have deep structures, the following syntax might be useful: from functools import reduce reduce(getattr, "a.b.c.d.e.f.g".split('.'), deepStructure)

@akki 2016-09-17 06:07:49

This is a very helpful answer, buy I couldn't work it out when the module foo is the current module itself. Does anybody know how to do that?

@Ben Hoyt 2016-12-20 19:06:31

@akki Yes, if you're in the foo module you can use globals() to do this: methodToCall = globals()['bar']

@KeatsKelleher 2017-10-23 01:12:38

You CAN do this, but SHOULD you? How will you find all instances of your function call when your code base gets large? There's nothing to grep for, and no IDE is going to find that reference. That makes this sort of dynamic call really troublesome. Isn't it nicer to your colleagues to be explicit, anyway? Less code doesn't doesn't always mean more readable.

@Patrick Johnmeyer 2017-11-13 16:17:43

@KeatsKelleher since we do not know the use case, only the question, all I can say reliably is that there are many use cases in which your point applies, and some which they do not. It is common and reasonable to do things like this in rules engines, DSLs, in-app scripting, etc., in which the code you are writing exists to run other code. There are probably numerous other "good" times to do this that I'm not thinking of right now. So, should we do this? The answer, as with most language features in most languages, is "it depends."

@KeatsKelleher 2017-11-13 16:21:36

@PatrickJohnmeyer I never exclude patterns/paradigms entirely... This is why I asked a question instead of making a blanket statement. There are a lot of negative repercussions for using this pattern overzealously... which (at least in my experience) is common.

@Eric Duminil 2018-02-26 21:45:18

Meh. I spent 10 minutes trying variations of foo.getattr('bar') and foo.get_attr('bar').

@Coolio2654 2018-04-10 18:26:20

No one else thank this great answer, for the sake of its current value.

@Jane 2018-07-13 08:53:36

I get ImportError: No module named 'foo' and when trying pip3 install foo get Could not find a version that satisfies the requirement foo (from versions: ) No matching distribution found for foo What's wrong?( I didn't understand

@Patrick Johnmeyer 2018-07-17 19:54:29

@Jane foo isn't a real module here, it is a placeholder for any module. Sorry for the confusion. I would consider editing the answer to use a real module, but it's been so heavily up-voted I'm not sure I should at this point.

@Dims 2018-12-12 07:56:45

Why are you calling function by string, but importing module by hardcoded name???

@Patrick Johnmeyer 2019-04-24 13:43:44

@Dims because that is the problem stated in the question. I have a module foo, and I have a string whose content is "bar". You could of course use strings for both.

@HS. 2008-08-07 11:35:23

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

@hoffmaje 2012-05-05 09:33:46

I do not understand that last comment. __import__ has its own right and the next sentence in the mentioned docs says: "Direct use of __import__() is rare, except in cases where you want to import a module whose name is only known at runtime". So: +1 for the given answer.

@glarrain 2013-08-05 22:07:01

Use importlib.import_module. The official docs say about __import__: "This is an advanced function that is not needed in everyday Python programming, unlike importlib.import_module()." docs.python.org/2/library/functions.html#__import__

@Xiong Chiamiov 2013-09-14 16:54:15

@glarrain As long as you're ok with only support 2.7 and up.

@cowlinator 2017-10-05 19:28:39

@Xiong Chaimiov, importlib.import_module is supported in 3.6 . See docs.python.org/3.6/library/…

@Xiong Chiamiov 2017-10-05 23:55:07

@cowlinator Yes, 3.6 is part of "2.7 and up", both in strict versioning semantics and in release dates (it came about six years later). It also didn't exist for three years after my comment. ;) In the 3.x branch, the module has been around since 3.1. 2.7 and 3.1 are now pretty ancient; you'll still find servers hanging around that only support 2.6, but it's probably worth having importlib be the standard advice nowadays.

@Dims 2018-12-12 07:57:08

What if module foo has nested name???

@tvt173 2016-12-07 18:29:30

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)

@iankit 2016-12-30 18:13:16

This would be risky. string can have anything and eval would end up eval-ling it without any consideration.

@tvt173 2017-01-06 18:48:51

Sure, you must be mindful of the context you are using it in, whether this will be appropriate or not, given those risks.

@red777 2018-08-14 11:01:13

A function should not be responsible for validating it's parameters - that's the job of a different function. Saying that it's risky to use eval with a string is saying that use of every function is risky.

@moi 2019-01-14 12:05:14

You should never use eval unless strictly necessary. getattr(__module__, method_name) is a much better choice in this context.

@user3946687 2016-10-24 13:20:46

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

@Sourcegeek 2012-08-19 09:40:43

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

@00500005 2014-04-09 10:17:41

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

@ferrouswheel 2013-10-16 00:24:22

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

@Pankaj Bhambhani 2015-12-16 13:19:27

This helped me. Its a lightweight version of __import__ function.

@Natdrip 2012-12-28 16:56:45

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

@V13 2016-07-29 12:26:33

In what aspect is this better than getattr() ?

@ioaniatr 2018-08-06 18:49:32

Exactly what i wanted. Works like a charm! Perfect!! self.__getattribute__('title') is equal to self.title

@ioaniatr 2018-08-16 16:52:40

self.__getattribute__('title') doesn't work in any cases(don't know why) afterall, but func = getattr(self, 'title'); func(); does. So, maybe is better to use getattr() instead

@Aran-Fey 2018-10-23 05:19:18

Can people who don't know python please stop upvoting this junk? Use getattr instead.

@trubliphone 2012-02-14 05:55:36

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)

@lony 2017-10-06 12:33:39

Just a bit more generic is handler = getattr(sys.modules[__name__], myFnName)

@sastanin 2009-05-07 12:45:13

locals()["myfunction"]()

or

globals()["myfunction"]()

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

@Joelmob 2014-10-09 21:36:28

This method with globals/locals is good if the method you need to call is defined in the same module you are calling from.

@Nick T 2015-01-26 20:51:36

@Joelmob is there any other way to get an object by string out of the root namespace?

@Joelmob 2015-01-27 12:34:43

@NickT I am only aware of these methods, I don't think there are any others that fill same function as these, at least I can't think of a reason why there should be more.

@David Stein 2017-01-30 15:18:12

I've got a reason for you (actually what led me here): Module A has a function F that needs to call a function by name. Module B imports Module A, and invokes function F with a request to call Function G, which is defined in Module B. This call fails because, apparently, function F only runs with the globals that are defined in Module F - so globals()['G'] = None.

Related Questions

Sponsored Content

13 Answered Questions

[SOLVED] How to substring a string in Python?

  • 2009-03-19 17:29:41
  • Joan Venge
  • 2443339 View
  • 1821 Score
  • 13 Answer
  • Tags:   python string

56 Answered Questions

[SOLVED] Calling an external command in Python

14 Answered Questions

[SOLVED] How to return multiple values from a function?

22 Answered Questions

[SOLVED] Converting string into datetime

  • 2009-01-21 18:00:29
  • Oli
  • 2361733 View
  • 1814 Score
  • 22 Answer
  • Tags:   python datetime

17 Answered Questions

[SOLVED] How to make a chain of function decorators?

12 Answered Questions

[SOLVED] How to import a module given its name?

  • 2008-11-19 06:09:57
  • Kamil Kisiel
  • 252346 View
  • 431 Score
  • 12 Answer
  • Tags:   python python-import

17 Answered Questions

[SOLVED] Does Python have a string 'contains' substring method?

32 Answered Questions

[SOLVED] How do I check if a string is a number (float)?

18 Answered Questions

18 Answered Questions

[SOLVED] Using global variables in a function

Sponsored Content