Reputation: 1163
Ive read a few posts with people struggling with this, spent a couple of hours trying various approaches but nothing has worked.
Very very simple, i just want to import code from a parent folder. The parent root folder of project has an empty init.py file
the structure is
__init__.py
services/
services/service_factory.py
etl/
etl/main.py
in the etl folder i am running python main.py
here is my main.py i've made it as simple as possible:
import sys, os
sys.path.append(os.path.abspath(os.path.join('..', 'services')))
from services.services_factory import *
print('hello world')
I get 'ModuleNotFoundError: No module named 'services' Can anyone explain what to change to get this to work?
Upvotes: 1
Views: 127
Reputation: 1776
This is always very cofusing. Relative imports are relative to the module structure. To test relative imports, you need to import your module in your main file (from outside the module). Let me try to show a case that works:
$ python test_module.py
Hello World!
Or you can make it an executable module and run it with python -m
(always from outside the module)
$ python -m module.etl
Hello World!
test_module.py
module
├── __init__.py [can be empty]
├── etl
├── __init__.py
├── __main__.py
│── services
├── service_factory.py
test_module.py
from module.etl import message
print(message)
service_factory.py
phrase = "Hello World"
mark = '!'
etl/__init__.py
from .__main__ import message
etl/__main__.py
from .. services.service_factory import phrase,mark
message = phrase+mark
if __name__ == "__main__":
#this block is run when executing `python -m module.etl`
print(message)
NOTE: if you add another file in etl
say etl/myscript.py
you can still execute it with python -m module.etl.myscript
(always from outside the module)
Upvotes: 1
Reputation: 567
Try to run it as a module, your cwd should be one level higher than main.py.
python -m etl.main
Upvotes: 0