python - абсолютный импорт для модуля в том же каталоге

У меня есть этот пакет:

mypackage/
    __init__.py
    a.py
    b.py

И я хочу импортировать вещи из модуля а в модуль б, имеет ли смысл писать в модуль б

from mypackage.a import *

или я должен просто использовать

from a import *

Оба варианта будут работать, мне просто интересно, что лучше (второй имеет смысл, потому что он находится на одном уровне, но я рассматриваю первый, чтобы избежать коллизий, например, если система работает из папки, содержащей файл с именем a.py).

2 ответа

Решение

Вы можете безопасно использовать номер 2, потому что не должно быть никаких коллизий - вы всегда будете импортировать модуль из того же пакета, что и текущий. Обратите внимание, что если ваш модуль имеет то же имя, что и один из модулей стандартной библиотеки, он будет импортирован вместо стандартного. Из документации:

Когда модуль с именем spam импортируется, интерпретатор сначала ищет встроенный модуль с таким именем. Если не найден, он ищет файл с именем spam.py в списке каталогов, заданных переменной sys.path, sys.path инициализируется из этих мест:

  • каталог, содержащий входной скрипт (или текущий каталог).
  • PYTHONPATH (список имен каталогов, с тем же синтаксисом, что и
  • переменная оболочки PATH).
  • зависящее от установки значение по умолчанию.

После инициализации программы Python могут изменить sys.path, Каталог, содержащий выполняемый скрипт, помещается в начало пути поиска, перед стандартным путем к библиотеке. Это означает, что скрипты в этом каталоге будут загружены вместо модулей с одинаковыми именами в каталоге библиотеки. Это ошибка, если замена не предназначена. Смотрите раздел Стандартные модули для получения дополнительной информации.

Опция from mypackage.a import * может быть использован по соображениям согласованности во всем проекте. В некоторых модулях вам все равно придется выполнять абсолютный импорт. Таким образом, вам не нужно будет думать, находится ли модуль в одном пакете или нет, и просто использовать единый стиль во всем проекте. Кроме того, этот подход является более надежным и предсказуемым.

Рекомендации по стилю Python не рекомендуют использовать относительный импорт:

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

Начиная с Python 2.5 был введен новый синтаксис для относительного импорта внутри пакета. Теперь вы можете . ссылаться на текущий модуль и .. ссылаясь на модуль на 1 уровень выше.

from . import echo
from .. import formats
from ..filters import equalizer

Вы должны использовать from mypackage.a import things, you, want,

Здесь есть две проблемы, основной из которых является относительный и абсолютный импорт, семантика которого изменилась в Python 3, и может быть дополнительно использована в Python 2.6 и 2.7 с использованием __future__ Импортировать. Используя mypackage.a, вы гарантируете, что получите тот код, который вам действительно нужен, и он будет надежно работать в будущих версиях Python.

Во-вторых, вам следует избегать импорта *, поскольку он может маскировать другой код. Что если файл a.py получил функцию с именем sum? Он бы молча переопределил встроенный. Это особенно плохо при импорте собственного кода в другие модули, так как вы можете использовать имена переменных или функций повторно.

Поэтому вам следует импортировать только те функции, которые вам нужны. Использование pyflakes в вашем исходном коде предупредит вас о возможных конфликтах.

Другие вопросы по тегам