Правильный импорт модулей в Python - PullRequest
11 голосов
/ 22 мая 2009

Как настроить импорт модулей, чтобы каждый модуль мог обращаться к объектам всех остальных?

У меня есть приложение Python среднего размера с файлами модулей в различных подкаталогах. Я создал модули, которые добавляют эти подкаталоги в sys.path и импортируют группу модулей, используя import thisModule as tm. Объекты модуля относятся к этой квалификации. Затем я импортирую этот модуль в другие с from moduleImports import *. Код сейчас небрежный и содержит несколько таких вещей, которые часто дублируют друг друга.

Во-первых, приложение не работает, поскольку некоторые ссылки на модули не назначены. Этот же код работает при модульном тестировании.

Во-вторых, я беспокоюсь, что у меня проблема с рекурсивным импортом модулей. Импорт moduleImports импортирует thisModule, который импортирует moduleImports. , , .

Как правильно это сделать?

Ответы [ 4 ]

23 голосов
/ 22 мая 2009

"У меня есть приложение Python среднего размера с файлами модулей в различных подкаталогах."

Хорошо. Убедитесь, что в каждом каталоге есть файл __init__.py, так что это пакет.

"Я создал модули, которые добавляют эти подкаталоги к sys.path"

Bad. Используйте PYTHONPATH или установите всю структуру Lib/site-packages. Не обновляйте sys.path динамически. Это плохо. Трудно управлять и поддерживать.

"импортирует группу модулей, используя import thisModule as tm."

Не имеет смысла. Возможно, у вас есть один import thisModule as tm для каждого модуля в вашей структуре. Это типичная стандартная практика: импортируйте только те модули, которые вам нужны, а не другие.

"Затем я импортирую этот модуль в другие с помощью from moduleImports import *"

Bad. Не стоит импортировать кучу случайных вещей.

Каждый модуль должен иметь длинный список конкретных вещей, которые ему нужны.

import this
import that
import package.module

Явный список. Нет магии. Нет динамического изменения на sys.path.

В моем текущем проекте сотни модулей, около дюжины пакетов. Каждый модуль импортирует только то, что ему нужно. Никакой магии.

6 голосов
/ 22 мая 2009

Несколько указателей

  1. Возможно, вы уже разделены функциональность в различном модуле. Если правильно сделано большую часть времени вы не попадет в круговой импорт проблемы (например, если модуль а зависит на б и б на а вы можете сделать третий модуль с, чтобы удалить такой круговой зависимость). В крайнем случае, в импорт б, но в б импорт а на точка, где требуется, например, внутри функция.

  2. Как только функциональность модули группируют их в пакеты под подкаталог и добавьте файл __init__.py чтобы вы могли импортировать пакет. Держите такие пакеты в папка, например lib, а затем либо добавить в sys.path или установить PYTHONPATH env переменная

  3. из модуля импорта * не может будь хорошей идеей Вместо этого импортируйте все нужно. Это может быть полностью квалифицированным. Это не повредит быть многословным. например из pakageA.moduleB import CoolClass.

4 голосов
/ 22 мая 2009

Способ сделать это - избежать магии. Другими словами, если ваш модуль требует чего-то от другого модуля, он должен импортировать это явно. Вы не должны полагаться на вещи, импортируемые автоматически.

Как и в дзэн Python (import this), явное лучше, чем неявное.

3 голосов
/ 22 мая 2009

Вы не получите рекурсию при импорте, потому что Python кэширует каждый модуль и не перезагружает тот, который уже есть.

...