#python #module #python-3.x #package #packaging
#python #модуль #python-3.x #пакет #упаковка
Вопрос:
У меня растет количество скриптов, составляющих программу, которую я пишу, и я решил, что пришло время очистить мое дерево исходных текстов и правильно их упаковать. Я уверен, что это простой вопрос, но я не могу выяснить, как это сделать.
Если у меня есть группа модулей, которые подходят друг другу, но один должен быть модулем верхнего уровня, а остальные должны иметь префикс имени модуля, но на самом деле переходить в пакеты более низкого уровня, как я могу это сделать.
Например, скажем, я хотел иметь возможность import mystuff
и получить весь mystuff. но я также должен уметь import mystuff.test.test1
. Я думал, что создам исходное дерево, подобное этому,
myprogram/
mystuff.py
mystuff/
__init__.py
tests/
__init__.py
test1.py
test2.py
...
Но в этом случае, похоже, он mystuff/
всегда имеет приоритет над mystuff.py
, поэтому import mystuff
ничего не делает (пока mystuff/
‘s __init__.py
пуст).
Каким был бы правильный подход для получения желаемого поведения? Или это невозможно, и я должен перейти mystuff.py
в mystuff/
и получить к нему доступ как mystuff.mystuff
(кажется, это ненужное повторение).
Извините, если я только что пропустил что-то очевидное. Я предполагаю, что это должно быть где-то задокументировано, но, похоже, я не могу найти, где что-то есть.
Обновить.Хотя я считаю, что метод Игнасио является правильным, мне это не очень нравится! Если у меня открыто несколько файлов в моем редакторе, и все они вызываются __init__.py
, все может запутаться. Итак, я решил оставить свою структуру такой, какая она есть, и связать mystuff.py
с mystuff/__init__.py
. Если у кого-нибудь есть какие-либо мнения о том, почему я не должен этого делать, я хотел бы их услышать.
На самом деле, в конце концов, я связываю наоборот, так как я не смог найти способ заставить distutils разыменовывать символические ссылки при создании tar.gz
, и в итоге я получил неработающие ссылки в своих выходных данных. Этот способ дает тот же эффект и делает его счастливым.
Комментарии:
1. ДА. Вы не должны этого делать, потому что ответ Ignatio является правильным.
2. @cwallenpoole. Согласен, но в конце концов, то, как я его настроил, дает точно тот же эффект. Даже
sdist
выходные данные будут точно такими же, как у Игнасио, без моих ссылок. Так что это просто облегчает мне разработку. Есть ли какая-то другая причина, по которой это плохо делать?
Ответ №1:
Вместо этого все, что находится в mystuff.py
, должно быть помещено в mystuff/__init__.py
.
Комментарии:
1. Я думал об этом. Но это казалось немного неприятным способом сделать это. Это все же рекомендуемый метод? Если да, то это то, что я сделаю, или это просто «способ, который будет работать»? Спасибо за ваш ответ.
2. Вот как это делается. Все, что находится в,
foo/__init__.py
станет частьюfoo
при импорте.3. ОК. Тогда это здорово. Вот так просто 🙂 Большое спасибо. (Будет приниматься, когда разрешено)
4. Вероятно, это должен быть отдельный вопрос, но поскольку это может быть просто быстрый ответ «да / нет», мне интересно, могу ли я спросить. Если
mystuff.py
это действительно скомпилированныйmystuff.so
(я использую cython), будет ли это по-прежнему работать. То есть будет__init__.so
прочитан, если он существует?5. Я не знаю наверняка, но я бы не стал это пробовать. Сделайте модуль C отдельным и импортируйте из него в
__init__.py
.
Ответ №2:
У вас не может быть одновременно mystuff.py
и mystuff/
пакета.
У вас есть два варианта:
- поместите код в
mystuff.py
вmystuff/__init__.py
- переименуйте
mystuff.py
, например, вmystuff/_stuff.py
, а затем импортируйте это вmystuff/__init__.py
.
Второй вариант выглядит примерно так:
myprogram/
mystuff.py -------
mystuff/
__init__.py /
_stuff.py <---
tests/
__init__.py
test1.py
test2.py
...
и mystuff/__init__.py
выглядит как:
from mystuff._stuff import *