Import module from file path
On 05/12/2018 02:30, Oscar Benjamin wrote:
> Hi all,
> I'm looking to import a module given a string representing the path to
> the .py file defining the module. For example given this setup
> mkdir -p a/b/c
> touch a/__init__.py
> touch a/b/__init__.py
> touch a/b/c/__init__.py
> touch a/b/c/stuff.py
> I have a module a.b.c.stuff which is defined in the file
> '/home/oscar/work/project/a/b/c/stuff.py'. Given that a.b.c.stuff is
> importable and I have the (relative or absolute) path of stuff.py as a
> string I would like to import that module.
> I want this to work in 2.7 and 3.4+ and have come up with the
> following which works for valid inputs:
I might try something along the lines of: (untested)
if not filename.endswith('.py'):
raise ValueError('not a .py file')
abs_filename = os.path.abspath(filename)
for path_root in sys.path:
abs_root = os.path.abspath(path_root)
rel_filename = os.path.relpath(abs_filename, abs_root)
if '.' in rel_filename[:-3]:
# '.' in directory names? can't be right!
mod_name = rel_filename[:-3].replace(os.sep, '.')
raise ValueError('not an importable module')
This should work with namespace packages.
> Also it seems as if there should be a simpler way to get from
> the path to the module name...
I doubt it. There's no reason for the import machinery to have such a
mechanism. Besides, not all modules have real file names (e.g. if they
live in zip files)