2010-11-17 10 views
57

mi chiedo circa il modo migliore per importare i pacchetti in un'applicazione Python. Ho uno struttura del pacchetto come questo:assoluta vs esplicita importazione relativo del modulo Python

project.app1.models 
project.app1.views 
project.app2.models 

project.app1.views importazioni project.app1.models e project.app2.models. Ci sono due modi per farlo, che ti vengono in mente.

Con importazioni assoluti:

import A.A 
import A.B.B 

o con le importazioni relative esplicite, come introdotti nella Python 2.5 with PEP 328:

# explicit relative 
import ..A 
import .B 

Qual è il modo più divinatorio di fare questo?

risposta

28

importazioni assoluti. Da PEP 8:

Le importazioni relative per le importazioni intra-pacchetto sono altamente scuse . Utilizza sempre il percorso assoluto del pacchetto per tutte le importazioni. Anche ora che PEP 328 [7] è pienamente implementato in Python 2.5, il suo stile delle importazioni rispetto esplicita è attivamente scoraggiati; importazioni assolute sono più portatile e di solito più leggibile.

Le importazioni relative esplicite sono una funzionalità di linguaggio piacevole (credo), ma non sono così esplicite come le importazioni assolute. La forma più leggibile è:

import A.A 
import A.B.B 

soprattutto se si importano diversi spazi dei nomi diversi. Se guardi alcuni progetti/tutorial ben scritti che includono le importazioni dai pacchetti, di solito seguono questo stile.

Le poche combinazioni di tasti che si richiedono per essere più esplicite salveranno altri (e forse voi) molto tempo in futuro quando stanno cercando di capire il vostro spazio dei nomi (specialmente se si passa a 3.x, in cui alcuni dei nomi dei pacchetti sono cambiati).

+1

Sì, non c'era l'ultima volta che ho letto attraverso PEP 8! –

+0

@Rafe, "guarda alcuni progetti ben scritti ..." qualche suggerimento? – denis

+0

@Denis: Rietveld è il progetto di Guido van Rossum, quindi immagino che sarebbe un buon posto per guardare (http://code.google.com/p/rietveld/). La libreria standard Python non è così grande, molto di quel codice non segue le convenzioni. –

27

Le importazioni relative non solo ti consentono di rinominare il pacchetto in un secondo momento senza cambiare dozzine di importazioni interne, ma ho anche avuto successo con loro nel risolvere alcuni problemi che riguardano cose come importazioni circolari o pacchetti namespace, perché non inviano Python "torna all'inizio" per avviare nuovamente la ricerca del modulo successivo dallo spazio dei nomi di primo livello.

+1

Questo è lo stile scoraggiato secondo la guida di stile di Python. Cloud leggono gravemente e non valgono la "convenienza" percepita a cui alludi. Se devi usare le importazioni relative per risolvere un problema, allora stai sbagliando. –

+7

Nota il suo commento (Brandon Rhodes) sull'altra risposta, con un link che mostra che non è più scoraggiato. –

+0

@RafeKettler puoi spiegare come useresti le importazioni assolute in un pacchetto che è incluso in un altro pacchetto? Le importazioni assolute falliranno nel pacchetto interno perché non conoscono il nuovo livello principale. Le importazioni relative continuano a funzionare. Si potrebbe probabilmente sostenere che il pacchetto non dovrebbe essere nidificato all'interno di un altro in primo luogo, ma un codice è pensato per essere riusabile e questo accade molto. Un sacco di codice riutilizzato non è confezionato per il pubblico e quindi non viene fornito come pacchetto separato, quindi i metodi ad-hoc come l'importazione/i sottomoduli VCS vengono utilizzati al posto – meowsqueak

89

Python importazioni relativi non sono più fortemente scoraggiate, ma utilizzando absolute_import è fortemente suggerito in quel caso.

Si prega di vedere this discussion citando Guido se stesso:

"Non è per lo più storica Fino alla nuova sintassi relativa importazione è stato implementato ci sono stati vari problemi con le importazioni relative La soluzione a breve termine era?. raccomandare di non usarli La soluzione a lungo termine era quella di implementare una sintassi non ambigua.Ora è il momento di ritirare l'anti-raccomandazione.Naturalmente, senza esagerare - I tuttora li trovo un gusto acquisito, ma loro avere il loro posto"

L'OP collega correttamente la PEP 328 che dice:

Diversi casi d'uso sono stati presentati, il più importante dei quali è essere in grado di riorganizzare la struttura dei pacchetti di grandi dimensioni senza dover modificare sub -packages. Inoltre, un modulo all'interno di un pacchetto non può facilmente importazione stesso senza le importazioni relative.

vedi anche domanda quasi duplicato When or why to use relative imports in Python

Naturalmente è ancora una questione di gusti. Mentre è più facile spostare il codice con le importazioni relative, ciò potrebbe anche interrompere in modo imprevisto le cose; e rinominare le importazioni non è così difficile.

per forzare il nuovo comportamento da PEP 328 uso:

from __future__ import absolute_import 

In questo caso, implicita relativa importazione non sarà più possibile (per esempio import localfile non funziona più, solo from . import localfile.). Per un comportamento pulito e a prova di futuro, è consigliabile utilizzare absolute_import.

Un avvertimento importante è che a causa di PEP 338 e PEP 366, le importazioni relative richiedono il file python per essere importato come modulo - non è possibile eseguire un file.py che ha un parente o di importazione si otterrà un ValueError: Attempted relative import in non-package.

Questa limitazione deve essere presa in considerazione quando si valuta l'approccio migliore. Guido è contro gli script in esecuzione da un modulo in ogni caso:

Sono -1 su questo e su altri twiddlings proposte del macchinario __main__. L'unico caso d'uso sembra essere l'esecuzione di script che si trovano nella directory di un modulo, che ho sempre visto come antipattern. Per farmi cambiare idea, dovresti convincermi che non lo è.

Discussioni esaurienti sull'argomento possono essere trovate su SO; ri. Python 3 questo è abbastanza completo:

+8

Guido ha scritto che nel 2010 è ancora nel PEP ? Come possiamo fidarci dei PEP se sono così obsoleti? – Jabba

+1

PEP sono come gli emendamenti statunitensi nel senso che è possibile modificare le cose. Ci sono anche molti PEPS respinti. I PEP sono delle proposte. Possono essere accettati, rifiutati o obsoleti, il che spesso significa nuovi PEP. PEP 8 è una guida di stile in modo che possa essere modificata sul posto. – CppLearner

+2

Sono confuso riguardo "un modulo all'interno di un pacchetto non può facilmente importare se stesso ..." parte. Non avevo mai sentito parlare di moduli che si importano da soli. – matiascelasco