I've attempted a few different techniques trying to do something that to me seems doable but I guess I am missing some gotchas about python (using 2.7 but would like this to work also for 3.* if possible).
I am not sure about terminology like package or module, but to me the following seems quite a "simple" doable scenario.
This is the directory structure:
.
├── job
│ └── the_script.py
└── modules
├── __init__.py
└── print_module.py
The content of the_script.py
:
# this does not work
import importlib
print_module = importlib.import_module('.print_module', '..modules')
# this also does not work
from ..modules import print_module
print_module.do_stuff()
The content of print_module
:
def do_stuff():
print("This should be in stdout")
I would like to run all this "relative paths" stuff as:
/job$ python2 the_script.py
But the importlib.import_module
gives various errors:
..modules.print_module
, then I get: TypeError("relative imports require the 'package' argument")
ValueError: Empty module name
On the other hand using the from ..modules
syntax I get: ValueError: Attempted relative import in non-package
.
I think the __init__.py
empty file should be enough to qualify that code as "packages" (or modules? not sure about the terminology), but it seems there's something I am missing about how to manage relative paths.
I read that in the past people was hacking this using the path
and other functions from import os
and import sys
, but according to the official docs (python 2.7 and 3.*) this should not be needed anymore.
What am I doing wrong and how could I achieve the result of printing the content modules/print_module.do_stuff
calling it from a script in the "relative directory" job/
?
If you follow the structure of this guide here: http://docs.python-guide.org/en/latest/writing/structure/#test-suite (highly recommend reading it all, it is very helpful) you will see this:
To give the individual tests import context, create a tests/context.py file:
import os import sys sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) import sample
Then, within the individual test modules, import the module like so:
from .context import sample
This will always work as expected, regardless of installation method.
Translated in your case this means:
root_folder
├── job
│ ├── context.py <- create this file
│ └── the_script.py
└── modules
├── __init__.py
└── print_module.py
In the context.py
file write the lines shown above, but import modules
instead of import samples
Finally in your the_script.py
: from .context import module
and you will be set to go!
Good luck :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With