2009-05-22 2 views
10

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

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

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

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

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

+0

Не знаю, отвечает ли это на ваш вопрос, но [я спросил об импорте несколько дней назад] (http://stackoverflow.com/questions/860672/lay-out-import-pathing-in-python- прямой и простой). Нашли ответы очень полезными. –

ответ

21

«У меня есть приложение 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.

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

+3

Обертка в одном предложении: «Явное лучше, чем неявное». –

3

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

+1

Круговой импорт может действительно произойти, например. предположим, что b определяет функцию, которая использует и обе импортирует друг друга. http://www.copypastecode.com/codes/view/5193 –

+0

@Anurag Uniyal: вы действительно протестировали это? импорт отслеживает, что он импортирует, поэтому нет никакой гарантии, что даже этот код вызовет рекурсивную загрузку. – SpliFF

+0

Это происходит, я не помню точные данные сейчас, но у него есть что-то с тем же самым модулем, который импортируется дважды в качестве основного, а затем как модуль –

6

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

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

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

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

+0

Незначительное примечание о форматировании. Я полагаю, вы имеете в виду __init__.py (используйте обратные элементы вокруг него, чтобы предотвратить его будучи преобразован в полужирный.) –

+0

спасибо, эти простые языки форматирования когда-то становятся сложными для управления –

+0

Я не понимаю, что вы подразумеваете под «разделенной функциональностью», или как третий модуль поможет решить взаимозависимость между двумя модулями. – chernevik

4

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

Как у Zen of Python (import this) есть, явное лучше, чем неявное.