DylanJaide
DylanJaide

Reputation: 395

Import module from different directory with import_module

I have a module in one directory that needs to be imported by a script in a different directory. However, whenever I try to import it, I get a ModuleNotFoundError. I have to keep these in separate directories due to being in separate git repos. Here's an example of my file structure:

└─ Documents
   ├─ ModuleRepo
   │  └─ myModule.py
   └─ ScriptRepo
      └─ myScript.py

The script myScript.py takes the module name as a command line argument, and then imports it using:

import importlib

def dynamic_import(module):
    return importlib.import_module(module)

if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('modulename', help='Specify the module to import', type=str)
    args = parser.parse_args()
    
    mymodule = dynamic_import(args.modulename)

If I navigate to Documents/ModuleRepo and try to run python3 ../ScriptRepo/myScript.py myModule, it gives the error ModuleNotFoundError: No module named 'myModule'. If I move myModule.py into Documents/ScriptRepo, then it runs successfully - so I guess python is looking for modules only in the directory of the script being run. This is especially strange to me, since this exact setup worked for me a few months ago, but now seemingly doesn't.

My minimal goal is to be able to navigate to Documents/ModuleRepo and run python3 ../ScriptRepo/myScript.py myModule. Ideally (but not necessarily), I would like to be able to be able to run myScript.py from anywhere, using relative paths to both myScript.py and myModule.py.

I've browsed many existing questions about dynamic imports using importlib, and even asked one of my own earlier this year, but I still have no idea how to solve this problem of having modules in completely separate directories. So any help would be appreciated.

Upvotes: 2

Views: 3552

Answers (2)

Coco Cat
Coco Cat

Reputation: 29

The following code snippets will allow you to load modules by explicitly defining the path to the required module(s):

For Python 3.5+ use:

import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
foo.MyClass()

For Python 3.3 and 3.4 use:

from importlib.machinery import SourceFileLoader

foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()

(Although this has been deprecated in Python 3.4.)

For Python 2 use:

import imp

foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()

Upvotes: 2

Mercury
Mercury

Reputation: 4171

Seems like it's a path problem. At the very top of myScript.py add:

import sys 
sys.path.append('..')

This should allow it to find the module.

Upvotes: 0

Related Questions