Reputation: 18
How is a Python package supposed to be structured to make everything possible for any module inside of it?
My file structure is as follows:
Project/
|---log/
| |---some logs
|
|---src/
|---foo/
| |---__init__.py
| |---analyse.py
| |---export.py
|
|---bar/
| |---__init__.py
| |---log.py
| |---dbhandler.py
|
|---__init__.py
|---main.py
main.py
initialises everything. I want to import foo/analyse.py
to bar/dbhandler.py
, but I only receive an error:
AttributeError: 'module' object has no attribute 'analyse'
I've tried several statements:
import Project.src.foo.analyse
import src.foo.analyse
import foo.analyse
import analyse
All of them give the same error. I've also tried:
from .. import foo.analyse
from .. import analyse
But I received:
ValueError: Attempted relative import beyond toplevel package
I've gone through about fifty threads on StackOverflow and countless articles on the internet. From everything I've found the import src.foo.*
statement should work from anywhere inside the package, if only the __init__.py
file is located in each folder.
Did anyone have the same problem?
Upvotes: 0
Views: 312
Reputation: 1930
Given your directory structure, on main.py you should have:
import foo.analyse
import bar.dbhandler
And then call like this (e.g.):
foo.analyse.number_cruncher()
bar.dbhandler.db_store()
if you start the program from the directory main.py
is in, it should work as it is. Otherwise you should check your PYTHONPATH
as Nicola Musatti suggests, or use a .pth file or any of the many options you have.
Upvotes: 1
Reputation: 18218
Ensure that your PYTHONPATH contains Project/src
and then use
import foo.analyse
Upvotes: 0
Reputation:
I think it should be
from ..foo import analyse
Since it's undetermined what ..
by itself means: that probably just refers to the top level package, so you have to state which other branch of your package tree you want to go down: foo
in this case.
With that, I can do (provided src
is on your PYTHONPATH
. In this case, I just started on the Project
directory level):
>>> import src
>>> import src.bar
>>> import src.bar.dbhandler
>>> src.bar.dbhandler.analyse
<module 'src.foo.analyse' from 'src/foo/analyse.py'>
>>> src.bar.dbhandler.analyse.__file__
'src/foo/analyse.py'
Also, as you may notice, with your current structure, the "main" package is called src
, since that's where your top-level __init__.py
lives. Possibly not what you want.
Upvotes: 1