Сделать каждый модуль в пакете доступным изнутри?

Как предполагается структурировать пакет Python, чтобы сделать все возможное для любого модуля внутри него?

Моя файловая структура выглядит следующим образом:

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 все инициализирует. Я хочу импортировать foo/analyse.py в bar/dbhandler.py, но я получаю только ошибку:

AttributeError: 'module' object has no attribute 'analyse'

Я пробовал несколько утверждений:

import Project.src.foo.analyse
import src.foo.analyse
import foo.analyse
import analyse

Все они дают одинаковую ошибку. Я также попробовал:

from .. import foo.analyse
from .. import analyse

Но я получил:

ValueError: Attempted relative import beyond toplevel package

Я просмотрел около пятидесяти статей о Stackru и бесчисленных статей в Интернете. Из всего, что я нашел import src.foo.* оператор должен работать из любого места внутри пакета, если только __init__.py файл находится в каждой папке.

У кого-нибудь была такая же проблема?

3 ответа

Решение

Убедитесь, что ваш PYTHONPATH содержит Project/src а затем использовать

import foo.analyse

Я думаю, что это должно быть

from ..foo import analyse

Так как это не определено, что .. само по себе означает: это, вероятно, просто относится к пакету верхнего уровня, поэтому вам нужно указать, какую ветвь дерева вашего пакета вы хотите перейти вниз: foo в этом случае.

С этим я могу сделать (при условии src на вашем PYTHONPATH, В этом случае я только начал Project уровень каталога):

>>> 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'

Также, как вы можете заметить, с вашей текущей структурой, "основной" пакет называется src, так как именно там ваш верхний уровень __init__.py жизни. Возможно, не то, что вы хотите.

Учитывая вашу структуру каталогов, на main.py вы должны иметь:

import foo.analyse
import bar.dbhandler

А затем позвоните так (например):

foo.analyse.number_cruncher()
bar.dbhandler.db_store()

если вы запустите программу из каталога main.py в, он должен работать как есть. В противном случае вы должны проверить свой PYTHONPATH как предполагает Никола Мусатти, или используйте файл.pth или любой из множества вариантов, которые у вас есть.

Другие вопросы по тегам