Reputation: 395
I have multiple projects that all need a common script (main.py
), but I need them to have different functions available that are specific to each project. This means that when I run the script for use in Project A, I want to be able to import its configA.py
, but to import configB.py
when running it for Project B.
For example, say that within both configA.py
and configB.py
, there is a different definition of the same function foo()
. My goal is to be able to run something along the lines of python3 main.py ../../ProjectA/Config/configA.py
for Project A, and similar for B. Then inside main.py
, the script would import the file passed to it (something like config = import_module(sys.argv[0])
), and then be able to run config.foo()
, which would behave differently depending on which file was passed.
From reading a number of help posts on SO, I've seen many people suggest importlib.import_module()
, since I can pass the package name as an argument to main.py
. But the slight complication compared to these other posts I've read is to do with my file structure. It seems like import_module()
only really works when the the main/package files are in the same directory, or when the main script is in a parent directory of the package. However, my file structure looks like this:
└─ Documents
├─ Common
│ └─ Scripts
│ └─ main.py
├─ ProjectA
│ └─ Config
│ └─ configA.py
└─ ProjectB
└─ Config
└─ configB.py
Is there a way for me to be able to import the package of my choice for use in main.py
given this file structure?
Upvotes: 1
Views: 228
Reputation: 36249
You can use an if statement for the different imports:
import os
import sys
sys.path.insert(0, os.abspath('../..')) # this is important so the packages are on the path
if sys.argv[1] == 'A':
from ProjectA.Config.configA import foo
elif sys.argv[1] == 'B':
from ProjectB.Config.configB import foo
else:
raise ImportError(f'No module corresponding to {sys.argv[1]}')
Or you can use also use importlib.import_module
instead of the if/else
chain:
import importlib
module = importlib.import_module('Project{x}.Config.config{x}'.format(x=sys.argv[1]))
foo = module.foo
And then use via
python main.py A # use foo from configA
python main.py B # use foo from ConfigB
-m
from Documents
An alternative to modifying sys.path
is to run the main.py
via the -m
switch from within the Documents
directory. When running python main.py
then the script's directory will be put on the path. When running python -m Common.Scripts.main
then the current working directory will be put on the path and hence ProjectA
and ProjectB
are automatically discoverable:
$ pwd
/path/to/Documents
$ python -m Common.Scripts.main
Upvotes: 1