DudeOnRock
DudeOnRock

Reputation: 3831

Different implementation of __import__() in Python 2.7 and Python 3.x

In Python 3 I got something like this to work:

def aFunctionImportingAndCallingAnotherFunction(functionName, args):
    packageString = "a_nested_package.to_be_imported.at_run_time"
    _temp = __import__(packageString, globals(), locals(), [functionName], 0)
    function = eval("_temp." + functionName)
    return function(args)

in Python 2.7 I get an error that the function I am passing in with functionName does not exist.

In this example the package a_nested_package is in sys.path, it has a package to_be_imported, which has a package at_run_time. All packages have __init__.py files.

I tried:

Also, if this is completely the wrong approach to do run-time imports of functions, please let me know! I am pretty new to Python (coming from C++, PHP and Java)

Upvotes: 0

Views: 383

Answers (2)

Eevee
Eevee

Reputation: 48546

__import__ works just like the import statement. (For good reason.)

When you do this:

import foo.bar.baz

You don't get a baz object in your file; you get foo! Likewise, this:

__import__('foo.bar.baz')

returns the foo module, but guarantees that it's been populated with bar.

So in your example, __import__ is returning a_nested_package, and you have to traverse the rest of the path yourself. Which sucks, and is why importlib is useful. :)

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1121614

Use the importlib module to dynamically import modules, then use getattr() to retrieve a specific name from that module:

import importlib

def aFunctionImportingAndCallingAnotherFunction(functionName, args):
    module = importlib.import_module(packageString)
    func = getattr(module, functionname)
    return func(*args)

Upvotes: 3

Related Questions