#python-3.x #pip
#python-3.x #pip
Вопрос:
У меня есть небольшой pip-пакет (назовем его my_package), который я написал на python3 со следующей структурой каталогов. Меня смущает несоответствие, которое я вижу при my_package.py
локальном запуске vs, когда я тестирую его, загружая его из PyPI, импортируя его в какой-то другой код, а затем запуская его.
.
| README.md
| LICENSE
| setup.py
| build
| dist
| my_package
| -- __init__.py
| -- my_package.py
| -- helpers
| ---- __init__.py
| ---- helper1.py
| ---- helper2.py
| ---- helper3.py
| ---- helper4.py
У my_package.py
меня есть следующий импорт:
from helpers import helper1
from helpers import helper2
from helpers import helper3
from helpers import helper4
Очевидно, что это всего лишь имена наполнителей, но суть в том, что я пытаюсь импортировать некоторый код из каталога помощников из my_package.py
скрипта.
Если бы я должен был запустить my_package.py локально мой код выполняется без каких-либо проблем — я думаю, что это ожидаемое поведение для python3. Однако, если я загружаю это в PyPI, а затем импортирую пакет, я получаю следующую ошибку:
Traceback (most recent call last):
File "test.py", line 1, in <module>
import my_package
File "/Users/fakeUser/.virtualenvs/pip-testing/lib/python3.7/site-packages/my_package/__init__.py", line 1, in <module>
from . my_package import main_function
File "/Users/fakeUser/.virtualenvs/pip-testing/lib/python3.7/site-packages/my_package/my_package.py", line 6, in <module>
from helpers import helper1
ModuleNotFoundError: No module named 'helpers'
Чтобы решить эту проблему, я изменил импорт, my_package.py
чтобы он выглядел следующим образом:
from .helpers import helper1
from .helpers import helper2
from .helpers import helper3
from .helpers import helper4
Насколько я понимаю, python3 использует .
, чтобы помочь разрешить относительный импорт. Это имело смысл попробовать для меня, потому что, если я бегу my_package.py
, добавление .
должно дать понять, что helpers
каталог находится в том же каталоге, my_package.py
что и . Внесение этой модификации фактически устраняет проблему с загрузкой пакета из pip, но теперь возникает следующая проблема, если я должен был запустить этот код локально:
Traceback (most recent call last):
File "my_package.py", line 6, in <module>
from .helpers import helper1
ModuleNotFoundError: No module named '__main__.helpers'; '__main__' is not a package
Я пытаюсь понять, что здесь происходит. В частности, если бы кто-нибудь мог объяснить следующее:
- Почему добавление
.
делает код несовместимым для локального использования? - Почему удаление
.
делает код несовместимым для использования из pip?
Я действительно хочу понять, почему этот импорт не работает, чтобы избежать подобных проблем в будущем.
Ответ №1:
Для начала ознакомьтесь с модулями в начале, используя следующий шаблон
my_package
| README.md
| LICENSE
| setup.py
| build
| dist
| src
| --my_package
| ---- __init__.py
| ---- helpers
| ------__init__.py
| ------ helper1.py
| ------ helper2.py
| ------helper3.py
| ------helper4.py
На данный момент вы можете определить верхний уровень __init__.py
пустым, а внутренний __init__.py
— в соответствии с тем, как helperx.py
он выглядит, а затем, когда вы устанавливаете модуль, вы можете вызвать helper1 соответствующим образом, например
from my_package.helpers import helper1
Комментарии:
1. Извините за отсутствие ясности в моем исходном сообщении, но у меня действительно есть init.py файлы настроены так, как вы указали; Я отредактирую исходный вопрос, чтобы включить это. Я думаю, что я действительно понял проблему, связанную с тем, как pip установит my_package как фактический пакет, тогда как запуск скрипта изнутри my_package еще не импортировал сам пакет и, следовательно, вызывает несоответствия импорта, о которых я спрашивал. Я собираюсь закрыть вопрос. Тем не менее, спасибо за ваш ответ.
2. Отлично, пожалуйста, примите / поддержите мой ответ, если он вам помог 🙂
Ответ №2:
Оригинальный плакат здесь:
Проблема была вызвана тем фактом, что pip установит пакет на уровне my_package
, поэтому полагаясь на то, что импорт будет настроен либо как .helpers
, либо my_package.helpers
как , тогда как запуск скрипта my_package.py
не устанавливает пакет, и поэтому импорт должен быть написан по-другому.
Я отмечу, что это правильный ответ как можно скорее (я считаю, что это будет завтра)