Вопрос-Ответ

Changes in import statement python3

Изменения в инструкции импорта python3

Я не понимаю следующего из pep-0404


В Python 3 неявный относительный импорт внутри пакетов больше недоступен - поддерживаются только абсолютный импорт и явный относительный импорт. Кроме того, звездообразный импорт (например, из x import *) разрешен только в коде уровня модуля.


Что такое относительный импорт? В каких еще местах star import был разрешен в python2? Пожалуйста, объясните на примерах.

Переведено автоматически
Ответ 1

Относительный импорт происходит всякий раз, когда вы импортируете пакет относительно текущего скрипта / пакета.

Рассмотрим для примера следующее дерево:

mypkg
├── base.py
└── derived.py

Теперь вам derived.py требуется что-то из base.py. В Python 2 вы могли бы сделать это следующим образом (в derived.py):

from base import BaseThing

Python 3 больше не поддерживает это, поскольку не указано явно, хотите ли вы "относительный" или "абсолютный" base. Другими словами, если бы в системе был установлен пакет Python с именем base, вы бы получили неправильный.

Вместо этого требуется использовать явный импорт, который явно указывает местоположение модуля на основе пути. Ваш derived.py будет выглядеть следующим образом:

from .base import BaseThing

В начале . написано "импортировать base из каталога модулей"; другими словами, .base сопоставляется с ./base.py.

Аналогично, есть .. префикс, который поднимается вверх по иерархии каталогов, например, ../..mod сопоставлением с ../mod.py), а затем ... который поднимается на два уровня выше (../../mod.py) и так далее.

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


@BrenBarn уже объяснял случай импорта star. Для полноты картины я должен сказать то же самое ;).

Например, вам нужно использовать несколько math функций, но вы используете их только в одной функции. В Python 2 вам разрешалось быть полу-ленивым:

def sin_degrees(x):
from math import *
return sin(degrees(x))

Обратите внимание, что это уже вызывает предупреждение в Python 2:

a.py:1: SyntaxWarning: import * only allowed at module level
def sin_degrees(x):

В современном коде Python 2 вы должны, а в Python 3 вы должны делать либо:

def sin_degrees(x):
from math import sin, degrees
return sin(degrees(x))

или:

from math import *

def sin_degrees(x):
return sin(degrees(x))
Ответ 2

Относительный импорт см. в документации. Относительный импорт - это когда вы импортируете из модуля относительно местоположения этого модуля, а не абсолютно из sys.path.

Что касается import *, Python 2 разрешил импорт звездочек внутри функций, например:

>>> def f():
... from math import *
... print sqrt

Для этого выдается предупреждение в Python 2 (по крайней мере, в последних версиях). В Python 3 это больше не разрешено, и вы можете выполнять звездообразный импорт только на верхнем уровне модуля (не внутри функций или классов).

Ответ 3

Для поддержки как Python 2, так и Python 3 используйте явный относительный импорт, как показано ниже. Они относятся к текущему модулю. Они поддерживаются начиная с версии 2.5.

from .sister import foo
from . import brother
from ..aunt import bar
from .. import uncle
Ответ 4

Добавлен еще один пример к ответу Михаила Гурни:

Обратите внимание, что относительный импорт основан на имени текущего модуля. Поскольку имя основного модуля всегда "__main__", модули, предназначенные для использования в качестве основного модуля приложения Python, всегда должны использовать абсолютный импорт.

2024-01-28 11:16 python python-3.x