#python #import #package
#python #импорт #пакет
Вопрос:
Прошло некоторое время, когда я боролся с импортом в пакетах. Когда я разрабатываю пакет, я везде читаю, что предпочтительнее использовать абсолютный импорт в подмодулях этого пакета. Я понимаю это, и мне это нравится еще больше. Но тогда мне не нравится, и я также читал, что вы не должны использовать sys.path.append('/path/to/package')
для использования вашего пакета в разработке…
Итак, мой вопрос в том, как вы разрабатываете такой пакет с нуля, используя непосредственно абсолютный импорт? На данный момент я разрабатываю пакет, используя относительный импорт, с тех пор я могу протестировать код, который я пишу перед упаковкой и установкой, затем я изменяю импорт, как только у меня есть релиз и я создаю пакет.
Каков правильный способ сделать это? Например, в Pycharm вы могли бы пометить папку как ‘source roor’ и иметь возможность работать так, как если бы папка пакета находилась в пути. Тем не менее, я читал, что это неправильный способ… чего мне не хватает? Как вы разрабатываете пакет во время тестирования его кода?
Ответ №1:
Ваш пробег может отличаться, но это то, что я обычно делаю:
Внутри пакета ( foo
) абсолютный ( import foo.bar
) или относительный ( import .bar
) для меня не имеет значения, пока это работает. Иногда я предпочитаю относительный, особенно когда проект большой и однажды я могу решить переместить несколько исходных файлов в подкаталог.
Как мне протестировать? Мой $PYTHONPATH
обычно имеет .
в нем, и моя иерархия каталогов выглядит следующим образом:
/path/to/foo_project
/setup.py
/foo
/__init__.py
/bar.py
/test
/test1.py
/test2.py
тогда скрипт в foo_project/test/test1.py
будет похож на то, что вы обычно используете в пакете, используя import foo.bar
. И когда я буду тестировать свой код, я буду находиться в каталоге foo_project
и запускать python test/test1.py
. Поскольку у меня есть .
в моем $PYTHONPATH
, он найдет каталог foo
и будет использовать его как пакет.
Комментарии:
1. Спасибо за информацию. Это действительно то, что я тоже делаю, относительный импорт, а затем папка tests / scripts package. Проблема с этим подходом заключается в том, что я не использую абсолютный импорт внутри пакета, и поэтому модули в подпакетах не могут получить доступ к модулям в других подпакетах. Когда иерархия плоская, как в вашем примере, этот подход работает хорошо, но когда у вас есть подпакеты, необходим абсолютный импорт. Вот почему я думаю, что абсолютный импорт предпочтителен и предлагается. Итак, остается главный вопрос: как люди, использующие абсолютный импорт, разрабатывают эти пакеты?
2. Относительный импорт все еще работает:
import ..bar.fubar
означает поиск../bar/fubar.py
3. Когда я пытаюсь использовать,
..
я обычно получаюValueError: attempted relative import beyond top-level package
. С этим еще предстоит разобраться. В любом случае, ваш ответ помог мне прояснить мои сомнения. Действительно,.
есть вPYTHONPATH
, поэтому я могу просто разработать пакет с абсолютным импортом и просто запуститьpython
из папки репозитория, содержащей папку package (/path/to/foo_project
). Пакет всегда будет находиться в path, и абсолютный импорт будет работать. Этого мне не хватало, вместе с тем фактом, что Python 3 устранил неявный относительный импорт. Спасибо за вашу помощь.4. Ошибка может быть вызвана тем, что у вас не было
__init__.py
в каталоге. Помогает даже файл с нулевым байтом. Это сигнал для Python о том, что каталог является частью пакета