Разве импорт не должен быть абсолютным по умолчанию в python27?
Представьте структуру каталогов:
/
a/
__init__.py
b.py
c.py
c.py
Файл /a/b.py
выглядит следующим образом:
import c
should_be_absolute = c
Все остальные файлы (включая __init__
) пусты.
При запуске теста script (с использованием python 2.7):
import a.b
print a.b.should_be_absolute
с PYTHONPATH=/
из пустого каталога (поэтому ничего не добавлено в PYTHONPATH
из текущего каталога) Я получаю
<module 'a.c' from '/a/c.py'>
где в соответствии с PEP 328 и утверждение import <> is always absolute
я бы ожидал:
<module 'c' from '/c.py'>
Вывод выполняется так, как ожидалось, когда я удаляю файл /a/c.py
.
Что мне не хватает? И если это правильное поведение - как импортировать модуль c
из b
(вместо a.c
)?
Update:
В соответствии с списком рассылки python dev это ошибка в документации. Импорт не по умолчанию в python27.
Ответы
Ответ 1
вам нужно добавить from __future__ import absolute_import
или использовать importlib.import_module('c')
на Python 2.7
По умолчанию используется Python 3.
В Python произошла ошибка: __future__.py
, и в ее заявке на документацию абсолютный импорт стал обязательным в 2.7, но они не.
Ответ 2
Если вы добавляете /
к вашему PYTHONPATH, тогда поисковый запрос все еще может искать c
в текущем каталоге. Было бы намного лучше, если бы вы разместили все под корневым пакетом и сослались на него абсолютно:
/myPackage
a/
__init__.py
b.py
c.py
__init__.py
c.py
И PYTHONPATH нравится: export PYTHONPATH=/:$PYTHONPATH
Итак, в вашем a.c
вы бы сделали и из них:
from myPackage import c
from myPackage.c import Foo
import myPackage.c
Таким образом, он всегда относится к вашему пакету.
Ответ 3
"Абсолют" не означает того, что вы думаете, что он делает; вместо этого это означает, что имеет место "обычная" процедура разрешения пакета: во-первых, она выглядит в каталоге пакета, затем во всех элементах sys.path; который включает элементы из PYTHONPATH.
Если вы действительно этого хотите, вы можете использовать такие инструменты, как модуль imp, но я бы рекомендовал против этого что-то вроде этого. Поскольку в общем случае вам никогда не придется создавать модуль с тем же именем, что и в стандартном дистрибутиве Python.