37
votes

How can I load a Python module in Python 3.4 given its full path?

A similar question How to import a module given the full path? covers Python versions before 3.4, but the conclusion is that support in Python 3.4 is deprecated for the presented answers, so any solution for Python 3.4 is appreciated.

Note that this question is not a duplicate of Import abitrary python source file. (Python 3.3+), since answers for this also use loader.load_module() which is deprecated in Python 3.4, as said in answer, with details in Consider leaving importlib.abc.Loader.load_module(), and documentation in importlib.

So a supported solution for module import by full path in Python 3.4 is needed.

4
Do not close. The answer given for 3.3+ doesn't work in 3.4 as stated by stackoverflow.com/a/67692 - Dan D.
Despite the "do not close" comment, it looks like the currently accepted answers in both questions currently show the same code. I think the questions should probably be merged. - Daniel Pryden

4 Answers

20
votes

This should work for all python files, regardless of file extension:

import importlib.machinery

modulename = importlib.machinery.SourceFileLoader('modulename','/Path/To/module.py').load_module()

This method was mentioned in the deprecation message in the imp.load_module documentation.

10
votes

The supported and non-deprecated method according to the 3.6 docs is like this:

def import_file(full_name, path):
    """Import a python module from a path. 3.4+ only.

    Does not call sys.modules[full_name] = path
    """
    from importlib import util

    spec = util.spec_from_file_location(full_name, path)
    mod = util.module_from_spec(spec)

    spec.loader.exec_module(mod)
    return mod
4
votes

The already-given answer works, but is unnecessarily clunky. An easier method:

import sys, os, importlib

sys.path.append(os.path.dirname(filename))
mname = os.path.splitext(os.path.basename(filename))[0]
imported = importlib.import_module(mname)                       
sys.path.pop()

imported is the imported module; you can use it as normal, through imported.method(arg). The final line isn't strictly necessary, but it's cleaner not to leave unnecessary entries in sys.path (particularly if you're going to run the code multiple times). This works in 3.4, and doesn't use anything marked as deprecated.

1
votes

The function below works in Python 3.4 - it is used to load and run specific functions in modules, but you need to add the folder to the sys path.

sys.path.append("path_to_your_file_to_import")
tool = {'file':'test_tool.py', 
    'function':'sum_even_numbers', 
    'args':['list'], 
    'return':['int']
}

args = [1,2,3]

def run(tool, args, silent='Y'):
        if silent == 'N':
            print('main called ' + tool['file'] + '->' + tool['function'] + ' with ', args, ' = ', tool['return'])
        mod = __import__( os.path.basename(tool['file']).split('.')[0])
        func = getattr(mod, tool['function'])
        tool['return'] = func(args)
        return tool['return']

Call it via

run(tool, args)