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) if abs_filename.startswith(abs_root): rel_filename = os.path.relpath(abs_filename, abs_root) if '.' in rel_filename[:-3]: # '.' in directory names? can't be right! continue mod_name = rel_filename[:-3].replace(os.sep, '.') try: return importlib.import_module(mod_name) except ImportError: continue else: 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) -- Thomas -- https://mail.python.org/mailman/listinfo/python-list