Änderungen in der Importanweisung python3

177

Ich verstehe das Folgende von pep-0404 nicht

In Python 3 sind implizite relative Importe innerhalb von Paketen nicht mehr verfügbar - nur absolute Importe und explizite relative Importe werden unterstützt. Außerdem sind Sternimporte (z. B. von x import *) nur im Code auf Modulebene zulässig.

Was ist ein relativer Import? An welchen anderen Orten war der Import von Sternen in Python2 erlaubt? Bitte erläutern Sie anhand von Beispielen.

balki
quelle

Antworten:

277

Der relative Import erfolgt immer dann, wenn Sie ein Paket relativ zum aktuellen Skript / Paket importieren.

Betrachten Sie zum Beispiel den folgenden Baum:

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

Nun, Sie derived.pybenötigen etwas von base.py. In Python 2 können Sie dies folgendermaßen tun derived.py:

from base import BaseThing

Python 3 unterstützt dies nicht mehr, da nicht explizit angegeben ist, ob Sie "relativ" oder "absolut" möchten base. Mit anderen Worten, wenn ein Python-Paket mit dem Namen baseim System installiert wäre, würden Sie das falsche erhalten.

Stattdessen müssen Sie explizite Importe verwenden, die den Speicherort eines Moduls auf pfadähnlicher Basis explizit angeben. Ihr derived.pywürde aussehen wie:

from .base import BaseThing

Der führende .sagt "Import baseaus Modulverzeichnis"; mit anderen Worten, .baseKarten zu ./base.py.

In ähnlicher Weise gibt es ein ..Präfix, das die Verzeichnishierarchie wie folgt ../(mit ..modZuordnung zu ../mod.py) und dann ...zwei Ebenen höher ( ../../mod.py) und so weiter.

Beachten Sie jedoch, dass sich die oben aufgeführten relativen Pfade auf das Verzeichnis derived.pybeziehen, in dem sich das aktuelle Modul ( ) befindet, nicht auf das aktuelle Arbeitsverzeichnis.


@BrenBarn hat den Fall des Sternimports bereits erklärt. Der Vollständigkeit halber muss ich dasselbe sagen;).

Zum Beispiel müssen Sie einige mathFunktionen verwenden, aber Sie verwenden sie nur in einer einzigen Funktion. In Python 2 durften Sie halb faul sein:

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

Beachten Sie, dass in Python 2 bereits eine Warnung ausgelöst wird:

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

Im modernen Python 2-Code sollten Sie und in Python 3 müssen Sie entweder Folgendes tun:

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

oder:

from math import *

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

Relative Importe finden Sie in der Dokumentation . Ein relativer Import ist, wenn Sie von einem Modul relativ zum Speicherort dieses Moduls importieren, anstatt absolut von sys.path.

Was import *, Python 2 erlaubt Sterne - Importe innerhalb von Funktionen, zum Beispiel:

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

Hierzu wird in Python 2 (zumindest in neueren Versionen) eine Warnung ausgegeben. In Python 3 ist dies nicht mehr zulässig und Sie können nur Sternimporte auf der obersten Ebene eines Moduls durchführen (nicht innerhalb von Funktionen oder Klassen).

BrenBarn
quelle
6
Warum wurde diese Entscheidung getroffen?
Dor
1
Ich vermute, dass die Idee dahinter lautet: "Explizit ist besser als implizit." aus PEP20 - Das Zen von Python. Der Punkt vor dem Modul macht die relative / nicht relative Verknüpfung explizit und löst so mögliche Namenskollisionen auf. Obwohl "Lesbarkeit zählt". leidet leicht.
Pafnucy
2
Nein, tatsächlich war es das "Gegenteil", "Praktikabilität schlägt Reinheit". Dies war notwendig, um den Zugriff auf lokale Variablen innerhalb von Funktionen zu optimieren, da der Compiler ohne "import *" immer nur durch Analyse des Codes weiß, welche Variablen lokal sind und direkt nachgeschlagen werden können. Tatsächlich verwenden Funktionen nicht einmal ein Diktat für die lokale Speicherung, sondern ein optimiertes Array, in dem Variablen eindeutige Indizes erhalten.
Veky
11

Verwenden Sie die folgenden expliziten relativen Importe, um sowohl Python 2 als auch Python 3 zu unterstützen. Sie beziehen sich auf das aktuelle Modul. Sie wurden ab 2.5 unterstützt .

from .sister import foo
from . import brother
from ..aunt import bar
from .. import uncle
Akseli Palén
quelle
14
import .brother gibt mir einen ungültigen Syntaxfehler in Python 3.5. Das ist normal? Ich habe init .py in dem Verzeichnis, in dem es sich befindet
Frikster
1
import .brotherist ungültige Syntax für Python 2 und 3
Rodrigo E. Principe
@ RodrigoE.Principe und so scheint es zu sein import ..uncle. Fest. Oh, was habe ich gedacht ... wurde wahrscheinlich von den Rittern abgelenkt, die Ni sagen!
Akseli Palén
4

Der Antwort von Michał Górny wurde ein weiterer Fall hinzugefügt:

Beachten Sie, dass relative Importe auf dem Namen des aktuellen Moduls basieren. Da der Name des Hauptmoduls immer " __main__" lautet , müssen Module, die als Hauptmodul einer Python-Anwendung verwendet werden sollen, immer absolute Importe verwenden.

Panfeng Li
quelle