Как работать с абсолютным импортом при разработке пакета

#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 о том, что каталог является частью пакета