Понимание операторов импорта в известных пакетах Python - PullRequest
0 голосов
/ 05 ноября 2018

Некоторые из созданных мною небольших проектов имеют такую ​​структуру каталогов:

my_project/
  ├─ docs/
  ├─ code/
  │    ├─ __init__.py
  │    ├─ main.py
  │    └─ tools.py
  ├─ README
  └─ .gitignore

и в main.py Я использую следующую инструкцию абсолютного импорта для импорта функции tool() из модуля tools.py:

from tools import tool

Когда я посмотрел исходный код некоторых известных (и, вероятно, также хорошо написанных) пакетов, я обнаружил похожую структуру, но другой стиль операторов абсолютного импорта:

( Django , /django/core/paginator.py)

from django.utils.functional import cached_property
from django.utils.inspect import method_has_no_args

Почему родительский каталог django включен в оператор импорта? И это предпочтительный способ, как импортировать модули? Когда я применяю логику к своему проекту и изменяю импорт функции tool() следующим образом:

from code.tests import test

и затем выполните следующую команду в терминале:

python3 main.py

это поднимает ModuleNotFoundError конечно.

Я хотел бы понять, почему эти пакеты используют этот стиль операторов импорта (который отличается от моего и не работает для моих собственных проектов). Я все еще изучаю Python, поэтому некоторые ссылки для чтения приветствуются.

1 Ответ

0 голосов
/ 05 ноября 2018

Это не ссылка на локальный каталог, как вы предполагали, а фактический модуль в его установленном пути.

Когда вы установите модуль, он будет доступен вашему интерпретатору Python как django, так что в основном он указывает, где установлен модуль. Интерпретатор в основном пытается сделать:

  1. есть ли django путь в моем текущем рабочем каталоге?
  2. если нет, есть ли django путь, на который я могу ссылаться в путях окружения?
  3. если нет, киньте ModuleNotFoundError.

Следуя этой логике, пакет использовал абсолютный импорт, поскольку paginator.py находится в пути django/core и, следовательно, не имеет доступа к пути django/utils, если он непосредственно не ссылается на себя как установленный модуль из site-packages или используя относительный импорт (from ..utils.functional import cached_property и т. д.). Эта ссылка содержит более подробную информацию.

Чтобы сравнить яблоки с яблоками в вашем случае - попробуйте использовать модуль test.py под my_project/utils. Вы заметите, что у вас будут проблемы с доступом к этому модулю в main.py без абсолютного или относительного импорта, потому что Python Interpreter знает только ваш текущий рабочий каталог (core, при условии, что вы используете main.py напрямую или где бы вы ни находились на самом деле выполнение вашего интерпретатора) и любые другие каталоги модулей, доступные через пути вашей среды.

...