8

Calling a function of a module from a string with the function's name in Python shows us how to call a function by using getattr("bar")(), but this assumes that we have the module foo imported already.

How would would we then go about calling for the execution of "foo.bar" assuming that we probably also have to perform the import of foo (or from bar import foo)?

Community
  • 1
  • 1
Xarses
  • 315
  • 3
  • 8

4 Answers4

3

Use the __import__(....) function:

http://docs.python.org/library/functions.html#import

(David almost had it, but I think his example is more appropriate for what to do if you want to redefine the normal import process - to e.g. load from a zip file)

user488551
  • 396
  • 1
  • 6
  • Works after a little coaxing, a better example should be given. I don't see a way to just import the function requested. >>> a = __import__("foo.bar", globals(), locals(), ['baz',], -1) >>> dir(a) ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'baz', 'wok', 'horn'] >>> – Xarses Jul 18 '11 at 21:51
  • I've finally revisited this. I'm accepting this because it put me in the direction I wanted. I've posted the final solution I've come up with – Xarses Nov 21 '11 at 16:39
  • I would also recommend looking into [importlib](https://docs.python.org/3.6/library/importlib.html#importlib.import_module): `from importlib import import_module` and then use `import_module(...)` in your code. It's a simplified `__import__` without all the args. – afeique Oct 10 '17 at 18:35
2

You can use find_module and load_module from the imp module to load a module whose name and/or location is determined at execution time.

The example at the end of the documentation topic explains how:

import imp
import sys

def __import__(name, globals=None, locals=None, fromlist=None):
    # Fast path: see if the module has already been imported.
    try:
        return sys.modules[name]
    except KeyError:
        pass

    # If any of the following calls raises an exception,
    # there's a problem we can't handle -- let the caller handle it.

    fp, pathname, description = imp.find_module(name)

    try:
        return imp.load_module(name, fp, pathname, description)
    finally:
        # Since we may exit via an exception, close fp explicitly.
        if fp:
            fp.close()
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
1

Here is what i finally came up with to get the function i wanted back out from a dottedname

from string import join

def dotsplit(dottedname):
    module = join(dottedname.split('.')[:-1],'.')
    function = dottedname.split('.')[-1]
    return module, function

def load(dottedname):
    mod, func = dotsplit(dottedname)
    try:
        mod = __import__(mod, globals(), locals(), [func,], -1)
        return getattr(mod,func)
    except (ImportError, AttributeError):
        return dottedname
Xarses
  • 315
  • 3
  • 8
0

this solution is not working? Calling a function of a module from a string with the function's name in Python

Community
  • 1
  • 1
fransua
  • 1,559
  • 13
  • 30