Jake
Jake

Reputation: 18

Making every module in a package accessible from within?

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

Answers (3)

deStrangis
deStrangis

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

Nicola Musatti
Nicola Musatti

Reputation: 18218

Ensure that your PYTHONPATH contains Project/src and then use

import foo.analyse

Upvotes: 0

user707650
user707650

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

Related Questions