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

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

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

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

Ответ 1

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

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

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

Ведущий . говорит 'import base из каталога модуля'; другими словами, .base отображается на ./base.py.

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

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


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

Например, вам нужно использовать несколько функций 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
import .brother
from ..aunt import bar
import ..uncle