Reputation: 395
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
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
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