Modifications de l'instruction d'importation python3

177

Je ne comprends pas ce qui suit de pep-0404

Dans Python 3, les importations relatives implicites dans les packages ne sont plus disponibles - seules les importations absolues et les importations relatives explicites sont prises en charge. De plus, les importations en étoile (par exemple à partir de x import *) ne sont autorisées que dans le code de niveau module.

Qu'est-ce qu'une importation relative? Dans quels autres endroits l'importation d'étoiles était-elle autorisée dans python2? Veuillez expliquer avec des exemples.

balki
la source

Réponses:

277

L'importation relative se produit chaque fois que vous importez un package par rapport au script / package actuel.

Prenons par exemple l'arbre suivant:

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

Maintenant, vous avez derived.pybesoin de quelque chose de base.py. Dans Python 2, vous pouvez le faire comme ceci (in derived.py):

from base import BaseThing

Python 3 ne prend plus en charge cela car il n'est pas explicite si vous voulez le "relatif" ou "absolu" base. En d'autres termes, s'il y avait un package Python nommé baseinstallé dans le système, vous vous tromperiez.

Au lieu de cela, il vous oblige à utiliser des importations explicites qui spécifient explicitement l'emplacement d'un module sur une base de chemin. Votre derived.pyressemblerait à:

from .base import BaseThing

Le premier .indique «importer basedepuis le répertoire du module»; en d'autres termes, .basecorrespond à ./base.py.

De même, il y a un ..préfixe qui monte dans la hiérarchie des répertoires comme ../(avec ..modmappage vers ../mod.py), puis ...qui monte de deux niveaux ( ../../mod.py) et ainsi de suite.

Veuillez cependant noter que les chemins relatifs listés ci-dessus étaient relatifs au répertoire dans lequel se trouve le module actuel ( derived.py), et non au répertoire de travail actuel.


@BrenBarn a déjà expliqué le cas de l'importation d'étoiles. Pour être complet, je vais devoir dire la même chose;).

Par exemple, vous devez utiliser quelques mathfonctions mais vous ne les utilisez que dans une seule fonction. Dans Python 2, vous étiez autorisé à être semi-paresseux:

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

Notez qu'il déclenche déjà un avertissement dans Python 2:

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

Dans le code Python 2 moderne, vous devriez et dans Python 3, vous devez faire soit:

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

ou:

from math import *

def sin_degrees(x):
    return sin(degrees(x))
Michał Górny
la source
14

Pour les importations relatives, consultez la documentation . Une importation relative se produit lorsque vous importez à partir d'un module par rapport à l'emplacement de ce module, au lieu d'absolument à partir de sys.path.

Quant à import *Python 2, il autorisait les importations d'étoiles dans les fonctions, par exemple:

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

Un avertissement est émis pour cela dans Python 2 (au moins les versions récentes). Dans Python 3, cela n'est plus autorisé et vous ne pouvez faire des importations en étoile qu'au niveau supérieur d'un module (pas à l'intérieur de fonctions ou de classes).

BrenBarn
la source
6
Pourquoi cette décision a-t-elle été prise?
Dor
1
Je suppose que l'idée sous-jacente est «l'explicite vaut mieux que l'implicite». de PEP20 - Le Zen de Python. Le point avant le module rend explicite la liaison relative / non relative, résolvant ainsi les éventuelles collisions de noms. Bien que «la lisibilité compte». souffre légèrement.
Pafnucy
2
Non, en fait, c'était la décision «contraire», «l'aspect pratique l'emporte sur la pureté». Cela était nécessaire pour optimiser l'accès aux variables locales à l'intérieur des fonctions, car sans "import *", le compilateur sait toujours simplement en analysant le code, quelles variables sont locales et peuvent être recherchées directement. En fait, les fonctions n'utilisent même pas de dict pour le stockage local, mais un tableau optimisé où les variables obtiennent des index uniques.
Veky
11

Pour prendre en charge à la fois Python 2 et Python 3, utilisez des importations relatives explicites comme ci-dessous. Ils sont relatifs au module actuel. Ils ont été pris en charge à partir de 2.5 .

from .sister import foo
from . import brother
from ..aunt import bar
from .. import uncle
Akseli Palén
la source
14
import .brother me donne une erreur de syntaxe non valide dans Python 3.5. C'est normal? J'ai init .py dans le répertoire dans
lequel
1
import .brothern'est pas une syntaxe invalide pour python 2 et 3
Rodrigo E. Principe
@ RodrigoE.Principe et semble donc être import ..uncle. Fixé. Oh, à quoi ai-je pensé ... j'ai probablement été distrait par les chevaliers qui disent Ni!
Akseli Palén
4

Ajout d'un autre cas à la réponse de Michał Górny:

Notez que les importations relatives sont basées sur le nom du module actuel. Puisque le nom du module principal est toujours " __main__", les modules destinés à être utilisés comme module principal d'une application Python doivent toujours utiliser des importations absolues.

Panfeng Li
la source