Modifiche nell'istruzione import python3


177

Non capisco quanto segue da pep-0404

In Python 3, le importazioni relative implicite all'interno dei pacchetti non sono più disponibili: sono supportate solo le importazioni assolute e le importazioni relative esplicite. Inoltre, le importazioni a stella (ad es. Da x import *) sono consentite solo nel codice a livello di modulo.

Che cos'è un'importazione relativa? In quali altri posti è stata consentita l'importazione di stelle in python2? Si prega di spiegare con esempi.

Risposte:


277

L'importazione relativa avviene quando si importa un pacchetto relativo allo script / pacchetto corrente.

Si consideri ad esempio il seguente albero:

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

Ora, il tuo derived.pyrichiede qualcosa da base.py. In Python 2, potresti farlo in questo modo (in derived.py):

from base import BaseThing

Python 3 non lo supporta più poiché non è esplicito se si desidera "relativo" o "assoluto" base. In altre parole, se ci fosse un pacchetto Python chiamato baseinstallato nel sistema, otterresti quello sbagliato.

Richiede invece l'uso di importazioni esplicite che specificano esplicitamente la posizione di un modulo su una base simile al percorso. Il tuo derived.pysarebbe simile a:

from .base import BaseThing

Il leader .dice "importa basedalla directory del modulo"; in altre parole, .basemappa a ./base.py.

Allo stesso modo, esiste un ..prefisso che sale alla gerarchia di directory come ../(con ..modmapping a ../mod.py), e quindi ...che sale di due livelli ( ../../mod.py) e così via.

Si noti tuttavia che i percorsi relativi sopra elencati erano relativi alla directory in cui derived.pyrisiede il modulo corrente ( ), non alla directory di lavoro corrente.


@BrenBarn ha già spiegato il caso dell'importazione a stella. Per completezza, dovrò dire lo stesso;).

Ad esempio, è necessario utilizzare alcune mathfunzioni ma le si utilizza solo in una singola funzione. In Python 2 ti è stato permesso di essere semi-pigro:

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

Si noti che attiva già un avviso in Python 2:

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

Nel moderno codice Python 2 dovresti e in Python 3 devi fare:

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

o:

from math import *

def sin_degrees(x):
    return sin(degrees(x))

14

Per le importazioni relative consultare la documentazione . Un'importazione relativa è quando si importa da un modulo rispetto alla posizione di quel modulo, invece che assolutamente da sys.path.

Per quanto riguarda import *, Python 2 ha consentito l'importazione di stelle all'interno di funzioni, ad esempio:

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

A questo proposito viene emesso un avviso in Python 2 (almeno versioni recenti). In Python 3 non è più consentito e puoi eseguire solo importazioni a stella al livello superiore di un modulo (non all'interno di funzioni o classi).


6
Perché è stata presa quella decisione?
Dor

1
La mia ipotesi è che l'idea alla base sia "Esplicito è meglio che implicito". da PEP20 - The Zen of Python. Il punto prima del modulo rende esplicito il collegamento relativo / non relativo risolvendo così possibili collisioni di nomi. Anche se "La leggibilità conta". soffre leggermente.
Pafnucy,

2
No, in effetti è stata la decisione "opposta", "la praticità batte la purezza". Ciò era necessario per ottimizzare l'accesso alle variabili locali all'interno delle funzioni, poiché senza "import *", il compilatore sa sempre semplicemente analizzando il codice, quali variabili sono locali e possono essere cercate direttamente. In effetti, le funzioni non usano nemmeno un dict per l'archiviazione locale, ma un array ottimizzato in cui le variabili ottengono indici univoci.
Veky,

11

Per supportare sia Python 2 che Python 3, utilizzare le importazioni relative esplicite come di seguito. Sono relativi al modulo corrente. Sono stati supportati a partire dalla 2.5 .

from .sister import foo
from . import brother
from ..aunt import bar
from .. import uncle

14
import .brother mi dà un errore di sintassi non valido in Python 3.5. E 'normale? Ho init .py nella directory in cui si trova
Frikster,

1
import .brothersintassi non valida sia per Python 2 che per 3
Rodrigo E. Principe,

@ RodrigoE.Principe e così sembra essere import ..uncle. Fisso. Oh, cosa stavo pensando ... probabilmente sono stato distratto dai cavalieri che dicono Ni!
Akseli Palén,

4

Aggiunto un altro caso alla risposta di Michał Górny:

Si noti che le importazioni relative si basano sul nome del modulo corrente. Poiché il nome del modulo principale è sempre " __main__", i moduli destinati all'uso come modulo principale di un'applicazione Python devono sempre utilizzare importazioni assolute.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.