198

I don't understand the following from pep-0404

In Python 3, implicit relative imports within packages are no longer available - only absolute imports and explicit relative imports are supported. In addition, star imports (e.g. from x import *) are only permitted in module level code.

What is a relative import? In what other places star import was allowed in python2? Please explain with examples.

balki
  • 26,394
  • 30
  • 105
  • 151

4 Answers4

302

Relative import happens whenever you are importing a package relative to the current script/package.

Consider the following tree for example:

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

Now, your derived.py requires something from base.py. In Python 2, you could do it like this (in derived.py):

from base import BaseThing

Python 3 no longer supports that since it's not explicit whether you want the 'relative' or 'absolute' base. In other words, if there was a Python package named base installed in the system, you'd get the wrong one.

Instead it requires you to use explicit imports which explicitly specify location of a module on a path-alike basis. Your derived.py would look like:

from .base import BaseThing

The leading . says 'import base from module directory'; in other words, .base maps to ./base.py.

Similarly, there is .. prefix which goes up the directory hierarchy like ../ (with ..mod mapping to ../mod.py), and then ... which goes two levels up (../../mod.py) and so on.

Please however note that the relative paths listed above were relative to directory where current module (derived.py) resides in, not the current working directory.


@BrenBarn has already explained the star import case. For completeness, I will have to say the same ;).

For example, you need to use a few math functions but you use them only in a single function. In Python 2 you were permitted to be semi-lazy:

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

Note that it already triggers a warning in Python 2:

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

In modern Python 2 code you should and in Python 3 you have to do either:

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

or:

from math import *

def sin_degrees(x):
    return sin(degrees(x))
mloskot
  • 37,086
  • 11
  • 109
  • 136
Michał Górny
  • 18,713
  • 5
  • 53
  • 76
15

For relative imports see the documentation. A relative import is when you import from a module relative to that module's location, instead of absolutely from sys.path.

As for import *, Python 2 allowed star imports within functions, for instance:

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

A warning is issued for this in Python 2 (at least recent versions). In Python 3 it is no longer allowed and you can only do star imports at the top level of a module (not inside functions or classes).

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • 6
    Why was that decision made? – Dor Nov 22 '13 at 09:29
  • 1
    My guess is that idea behind it is 'Explicit is better than implicit.' from PEP20 - The Zen of Python. Dot before module makes relative/nonrelative linking explicit thus resolving possible name collisions. Although 'Readability counts.' suffers slightly. – Pafnucy Sep 03 '15 at 11:01
  • 2
    No, in fact it was the "opposite", "practicality beats purity" decision. That was necessary in order to optimize local variable access inside functions, since without "import *", compiler always knows just by analyzing the code, what variables are local and can be looked up directly. In fact, functions don't even use a dict for local storage, but an optimized array where variables get unique indices. – Veky Sep 24 '15 at 11:06
14

To support both Python 2 and Python 3, use explicit relative imports as below. They are relative to the current module. They have been supported starting from 2.5.

from .sister import foo
from . import brother
from ..aunt import bar
from .. import uncle
Akseli Palén
  • 27,244
  • 10
  • 65
  • 75
4

Added another case to Michał Górny's answer:

Note that relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application must always use absolute imports.

L3viathan
  • 26,748
  • 2
  • 58
  • 81
Panfeng Li
  • 3,321
  • 3
  • 26
  • 34
  • This is wrong. Relative imports are based off of `__package__`. And the module level `__package__` attribute is writable, so even when `__name__ == "__main__"` [you can specify where you want relative imports to resolve by setting a `__package__` attribute](https://tio.run/##Tcw9DoAgDEDhnVM0TLK4OHuWpuFHidASrIOnRxMXx/cNr926Cy9jtJ5ZJ0SmGhGdQWzkD9regBWsl1Ki1yx8WpO6VJgh1yZdIcREV9GQvZrv8hM3xgM). – wim Dec 01 '22 at 07:17