2010-11-17 1 views
57

Мне интересно, как выбрать импорт пакетов в приложении Python. У меня есть структура пакета вроде этого:Абсолютный и явный относительный импорт модуля Python

project.app1.models 
project.app1.views 
project.app2.models 

project.app1.views импорт project.app1.models и project.app2.models. Есть два способа сделать это, которые приходят на ум.

При абсолютном импорте:

import A.A 
import A.B.B 

или с явным относительным импортом, как и введенным в Python 2.5 with PEP 328:

# explicit relative 
import ..A 
import .B 

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

ответ

28

Абсолютный импорт. От ОПТОСОЗ 8:

Относительный импорт для внутрипанельных импортных поставок - очень высокий обескуражен. Всегда используйте абсолютный путь пакета для всего импорта. Даже теперь, когда PEP 328 [7] полностью реализован в Python 2.5, , его стиль явного относительного импорта активно обескуражен; Абсолютный импорт более портативный и обычно более читаемый.

Явный относительный импорт - отличная языковая функция (я думаю), но они не так явно выражены, как абсолютный импорт. Более читаемая форма:

import A.A 
import A.B.B 

особенно если вы импортируете несколько разных пространств имен. Если вы посмотрите на некоторые хорошо написанные проекты/учебники, которые включают импорт из пакетов, они обычно следуют этому стилю.

Несколько лишних нажатий клавиш, которые вы принимаете, чтобы быть более ясными, могут спасти других (и, возможно, вам) много времени в будущем, когда они попытаются выяснить ваше пространство имен (особенно если вы перейдете на 3.x, в котором некоторые имена пакетов были изменены).

+1

Да, он не был там последний раз, когда я прочитал PEP 8! –

+0

@ Rafe, «посмотрите на некоторые хорошо написанные проекты ...» любые предложения? – denis

+0

@Denis: Rietveld - собственный проект Guido van Rossum, поэтому я бы предположил, что это будет хорошее место для поиска (http://code.google.com/p/rietveld/). Стандартная библиотека Python не так велика, многие из этого кода не соответствуют соглашениям. –

27

Относительный импорт не только позволяет вам свободно переименовывать ваш пакет позже, не меняя десятки внутренних импортов, но я также имел успех с ними в решении определенных проблем, связанных с такими вещами, как циклический импорт или пакеты пространства имен, поскольку они не отправляют Python «назад к началу», чтобы снова начать поиск следующего модуля из пространства имен верхнего уровня.

+1

Это обескураженный стиль в соответствии с руководством по стилю Python. Они облачно читают удобочитаемость и не стоят воспринимаемого «удобства», о котором вы говорите. Если вам нужно использовать относительный импорт для решения проблемы, тогда вы делаете это неправильно. –

+7

Обратите внимание, что его (Брэндон Роудс) комментирует другой ответ, со ссылкой, что его больше не обескураживают. –

+0

@ RafeKettler вы можете объяснить, как использовать абсолютный импорт в пакете, который сам входит в другой пакет? Абсолютный импорт не будет выполнен во внутреннем пакете, потому что они не знают о новом верхнем уровне. Относительный импорт продолжает работать. Можно было бы, вероятно, утверждать, что пакет не должен быть вложен в другое в первую очередь, но некоторый код предназначен для повторного использования, и это происходит очень часто. Много повторного кода не упакован для публики и поэтому не предоставляется в виде отдельного пакета, поэтому вместо этого используются специальные методы, такие как импорт/подмодули VCS. – meowsqueak

89

Относительный импорт Python уже не сильно обескуражен, но в этом случае настоятельно рекомендуется использовать absolute_import.

Пожалуйста см this discussion не ссылаясь сам Гвидо:

«Разве это в основном исторический До нового относительного импорта синтаксиса был реализован были различные проблемы с относительными импорта краткосрочное решение было?. рекомендовать не использовать их. Долгосрочное решение состояло в том, чтобы реализовать однозначный синтаксис. Теперь пришло время, чтобы снял антирекомендацию. Конечно, не переходя за борт - я все еще нахожу их приобретенным вкусом, но они имеют свое место."

ОП правильно связывает PEP 328, который говорит: были представлены

Несколько вариантов использования, наиболее важными из которых являются , способного изменить структуру больших пакетов без редактирования подразделов -packages. Кроме того, модуль внутри пакета не может легко импорт себя без относительного импорта.

Также см почти дубликат вопрос When or why to use relative imports in Python

Конечно, это все еще стоит как бы по вкусу. Хотя легче перемещать код с относительным импортом, это также может неожиданно нарушить вещи; и переименование импорта не так уж сложно.

Чтобы заставить новое поведение из PEP 328 использования:

from __future__ import absolute_import 

В этом случае неявный относительный импорт больше не будет возможным (например, import localfile больше не будет работать, только from . import localfile.). Для чистого и будущего поведения, рекомендуется использовать absolute_import.

Важное предостережение, что из-за PEP 338 и PEP 366, относительный импорт необходим файл питона, чтобы импортировать как модуль - вы не можете выполнить file.py, который имеет относительный импорт или вы получите ValueError: Attempted relative import in non-package.

Это ограничение следует учитывать при оценке наилучшего подхода. В любом случае Гвидо выступает против запуска скриптов из модуля:

Я нахожусь на этом и на любых других предлагаемых твидлингах машины __main__. Единственный случай использования, похоже, заключается в том, что скрипты выполняются внутри каталога модуля, который я всегда рассматривал как антипаттерн. Чтобы заставить меня передумать, вы должны были бы убедить меня, что это не так.

Исчерпывающие обсуждения по этому вопросу можно найти на SO; число рейнольдса Python 3 это весьма всеобъемлющий:

+8

Гвидо написал, что в 2010 году он все еще находится в PEP? Как мы можем доверять PEP, если они настолько устарели? – Jabba

+1

PEP похожи на поправки США в том смысле, что вы можете изменить их. Есть много отклоненных PEPS тоже. PEP - это предложения. Они могут быть приняты, отвергнуты или устарели, что часто означает новый PEP. PEP 8 - это руководство по стилю, поэтому его можно модифицировать на месте. – CppLearner

+2

Я смущен о том, что «модуль внутри пакета не может легко импортировать себя ...». Раньше я никогда не слышал об импорте модулей. – matiascelasco