Python 3.4: How to import a module given the full path?
Question:
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.
Answers:
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)
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.
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.
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
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.
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)
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.
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.
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