Zubda
Zubda

Reputation: 963

Python project structure, project main file import helpers

Here is my project structure.

[~/Sandbox/pystructure]:$ tree
.
├── pystructure
│   ├── __init__.py
│   ├── pystructure.py
│   └── utils
│       ├── eggs
│       │   ├── base.py
│       │   └── __init__.py
│       ├── __init__.py
│       └── spam.py
├── README.md
└── requirements.txt

3 directories, 8 files

and these are the contents of the files,

[~/Sandbox/pystructure]:$ cat pystructure/utils/spam.py 
def do():
    print('hello world (from spam)!')

[~/Sandbox/pystructure]:$ cat pystructure/utils/eggs/base.py 
def do():
    print('hello world (from eggs)!')

[~/Sandbox/pystructure]:$ cat pystructure/utils/eggs/__init__.py 
from .base import do

[~/Sandbox/pystructure]:$ cat pystructure/pystructure.py 
#!/usr/bin/python3

from .utils import spam, eggs

def main():
    spam.do()
    eggs.do()

if __name__ == '__main__':
    main()

However when I try running the app like this I get this error,

[~/Sandbox/pystructure]:$ python3 pystructure/pystructure.py 
Traceback (most recent call last):
  File "pystructure/pystructure.py", line 3, in <module>
    from .utils import spam, eggs
ModuleNotFoundError: No module named '__main__.utils'; '__main__' is not a package

or when I try running the code from within the directory that the file is created in (which is not my desire, as I want to run it as a service or using cron),

[~/Sandbox/pystructure]:$ cd pystructure/

[~/Sandbox/pystructure/pystructure]:$ python3 pystructure.py 
Traceback (most recent call last):
  File "pystructure.py", line 3, in <module>
    from .utils import spam, eggs
ModuleNotFoundError: No module named '__main__.utils'; '__main__' is not a package

However if I import it, it does work (only from the base dir, however...)

[~/Sandbox/pystructure/pystructure]:$ cd ..

[~/Sandbox/pystructure]:$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pystructure import pystructure
>>> pystructure.main()
hello world (from spam)!
hello world (from eggs)!
>>> 

(if I try importing it from the directory it resides in I get this error),

[~/Sandbox/pystructure]:$ cd pystructure/

[~/Sandbox/pystructure/pystructure]:$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pystructure
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "~/Sandbox/pystructure/pystructure/pystructure.py", line 3, in <module>
    from .utils import spam, eggs
ImportError: attempted relative import with no known parent package
>>> 

I believe my problems come from not having a full understanding on PYTHONPATH, I tried googling, but I haven't yet found my answer... Any insights please.

Upvotes: 3

Views: 1948

Answers (1)

Benjamin Kozuch
Benjamin Kozuch

Reputation: 150

When you import from a package, you are importing from the __init__.py of that package....

so in your utils package, your __init__.py is empty.

trying adding this to your utils/__init__.py

print("utils/__init__.py")
from . import eggs
from . import spam

Now, when you say from utils import eggs, spam you are saying, from the init.py of the utils package, import the things that I imported in there.

Also, in pystructure.py

change this

from .utils import  eggs, spam 

into this

from utils import  eggs, spam 

Upvotes: 2

Related Questions