2012-05-08 1 views
40

Ho due situazioni specifiche in cui io non capisco come l'importazione di opere in Python:Come funziona esattamente l'importazione Python?

prima situazione specifica:

Quando importo lo stesso modulo in due diversi script Python, il modulo non è importato due volte, giusto? La prima volta che Python lo incontra, viene importato e, una seconda volta, controlla se il modulo è stato importato o se ne fa una copia?

seconda situazione specifica:

Si consideri il seguente modulo, chiamato bla.py:

a = 10 

E poi, abbiamo foo.py, un modulo che importa bla.py:

from bla import * 

def Stuff(): 
    return a 

E dopo di ciò, abbiamo uno script chiamato bar.py, che viene eseguito dall'utente:

from foo import * 
Stuff() #This should return 10 
a = 5 
Stuff() 

Qui non so: Fa Stuff() ritorno 10 o 5?

+12

Cosa è successo quando hai eseguito il codice? – geoffspear

+0

Potresti trovare questi interessanti: http://lucumr.pocoo.org/2011/9/21/python-import-blackbox/ e http://lucumr.pocoo.org/2009/7/24/singletons-and- loro-problemi-in-python /. Entrambi trattano le importazioni in Python. – rubik

risposta

50

Parte 1

Il modulo è caricato solo una volta, quindi non c'è perdita di prestazioni mediante l'importazione di nuovo. Se si desidera effettivamente che venga caricato/analizzato nuovamente, è necessario il modulo reload().

Il primo posto selezionato è sys.modules, la cache di tutti i moduli che sono stati importati in precedenza. [source]


Parte 2

from foo import * importazioni a al campo di applicazione locale. Quando si assegna un valore a a, viene sostituito con il nuovo valore, ma la variabile originale foo.a non viene toccata.

Quindi, a meno che non si sia import foo e si modifichi foo.a, entrambe le chiamate restituiranno lo stesso valore.

Per un tipo mutabile come un elenco o dettato sarebbe diverso, la modifica influirebbe effettivamente sulla variabile originale, ma l'assegnazione di un nuovo valore non modificherà ancora foo.whatever.

Se volete informazioni più dettagliate, dare un'occhiata a http://docs.python.org/reference/executionmodel.html:

I seguenti costrutti legano nomi: parametri formali a funzioni, istruzioni import, le definizioni di classe e funzione (legano la classe o nome funzione nel blocco di definizione) e obiettivi identificativi se si verificano in un'assegnazione, per l'intestazione del ciclo, nella seconda posizione di un'intestazione della clausola except o dopo come in un'istruzione with.

Le due sezioni in grassetto sono quelli rilevanti per voi: in primo luogo il nome a è legata al valore della foo.a durante l'importazione. Quindi, quando si esegue a = 5, il nome a è associato a 5. Poiché la modifica di una lista/dict non causa alcun binding, tali operazioni modificano quella originale (b e sono associati allo stesso oggetto su cui si opera). Assegnare un nuovo oggetto a b sarebbe di nuovo un'operazione vincolante e quindi separare b da foo.b.

E 'anche interessante notare che cosa esattamente il import dichiarazione fa:

  • import foo lega il nome del modulo per l'oggetto modulo nell'ambito corrente, quindi se si modifica foo.whatever, si lavorerà con il nome in quella modulo - eventuali modifiche/assegnazioni influenzeranno la variabile nel modulo.
  • from foo import bar lega il nome dato (s) solo (cioè foo rimarranno non legato) per l'elemento con lo stesso nome in foo - così operazioni sui bar si comportano come spiegato in precedenza.
  • from foo import * si comporta come il precedente, ma importa tutti i nomi globali che non hanno come prefisso un carattere di sottolineatura. Se il modulo definisce __all__, vengono importati solo i nomi all'interno di questa sequenza.

Parte 3 (che non esiste nemmeno nella tua domanda: p)

La documentazione pitone è estremamente buono e di solito verbose - a trovare risposta a quasi ogni possibile linguaggio-correlati domanda in là. Ecco alcuni link utili:

2

Per rispondere alla tua prima domanda:

No, python non viene "importato" due volte. Quando Python carica un modulo, controlla il modulo in sys.modules. Se non è lì, viene inserito e caricato.

Per rispondere alla tua seconda domanda:

moduli possono definire quali nomi saranno esportare in uno scenario from camelot import *, e il comportamento è quello di creare i nomi per i valori esistenti, senza fare riferimento a variabili esistenti (python non ha riferimenti).

Su un argomento un po 'correlato, fare un from camelot import * è not the same as a regular import.

+0

Sembra che ThiefMaster mi abbia battuto per rispondere alla modifica. Lascio questo qui solo per mantenere il "" da importazione Camelot * 'non è la stessa di un'importazione normale." – Darthfett