pythonpython-importpython-modulepython-packaging

Python - import function from parallel directory


Let's assume I have two parallel directories, with simple python files.
--'dir_one' with file_one.py
--'dir_two' with file_two.py

In file_one.py there is a function named function_one. How can I import it within file_two.py? I have checked literally a few dozens of sources, including answers on stackoverflow. Therefore, I am not quoting any of them here. I have tried four different soulutions, none of them works.

  1. Insert 'init.py' files in all the directories - results in error 'ImportError: attempted relative import with no known parent package'
  2. Make both directories a single package - not possible in this case, directories have to be able to run as independent apps.
  3. Use sys module: sys.path.insert(0, 'path-to-dir_one') right before 'import dir_one' line - doesn't change anything, still get 'ModuleNotFoundError: No module named 'dir_one'.
  4. try relative import: 'from .dir_one import file_one' - 'ModuleNotFoundError: No module named 'zweizen.prodalitics'.

Is it possible at all to import a function in python from parallel folder without making it part of the same package?


Solution

  • You can add directly load the module to sys.modules using importlib to import it. I assume you are working with a directory structure similar to this.

    Directory Structure

    file1.py

    a = 10
    

    file2.py

    
    import os
    
    def import_from_path(module_name:str, file_path: str):
        import importlib.util
        spec = importlib.util.spec_from_file_location(module_name, file_path)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)
        return module
    
    file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../dir1/file1.py'))
    module_name = "file1"
    
    file1 = import_from_path(module_name, file_path)
    
    print(file1.a)
    
    

    You can import any python file as a module using this method and you don't modify the system path too.