Una fonte di difficoltà con questa domanda è che si dispone di un programma di nome bar/bar.py
: import bar
importazioni sia bar/__init__.py
o bar/bar.py
, a seconda di dove lo si fa, che lo rende un po 'ingombrante per tenere traccia che a
è bar.a
.
Ecco come funziona:
La chiave per capire ciò che accade è rendersi conto che nella tua __init__.py
,
from bar import a
in effetti fa qualcosa di simile
a = bar.a # … with bar = bar/bar.py (as if bar were imported locally from __init__.py)
e definisce una nuova variabile (bar/__init__.py:a
, se lo si desidera). Pertanto, il numero from bar import a
in __init__.py
associa il nome bar/__init__.py:a
all'oggetto originale bar.py:a
(None
). Questo è il motivo per cui si può fare from bar import a as a2
in __init__.py
: in questo caso, è chiaro che avete sia bar/bar.py:a
e distinta nome della variabile bar/__init__.py:a2
(nel tuo caso, i nomi delle due variabili appena capita di essere entrambi a
, ma vivono ancora in diversi spazi dei nomi: in __init__.py
, sono bar.a
e a
).
Ora, quando si fa
import bar
print bar.a
si accede a variabili bar/__init__.py:a
(dal import bar
Le importazioni della vostra bar/__init__.py
). Questa è la variabile che modifichi (in 1). Non stai toccando il contenuto della variabile bar/bar.py:a
. Così, quando in seguito si fa
bar.foobar()
si chiama bar/bar.py:foobar()
, che accede variabile a
da bar/bar.py
, che è ancora None
(quando foobar()
è definito, si lega i nomi delle variabili una volta per tutte, in modo che il a
in bar.py
è bar.py:a
, nessuna altra variabile a
definita in un altro modulo, poiché potrebbero esserci molte variabili a
in tutti i moduli importati). Da qui l'ultima uscita None
.
In realtà, trovo la P il modo di importare di ython è molto più pulito di quello di Java, perché gli spazi dei nomi/gli ambiti devono sempre essere separati correttamente e non interferire mai l'uno con l'altro in modi imprevisti. Come qui: la modifica di un'associazione di un oggetto a un nome in uno spazio dei nomi (leggi: assegnazione di qualcosa alla proprietà globale di un modulo) non influisce mai su altri spazi dei nomi (leggi: il riferimento che è stato importato) in Python. Ma lo fa in Java, ecc. In Python hai solo bisogno di capire cosa viene importato, mentre in Java, devi anche capire l'altro modulo nel caso, altera questo valore importato in seguito. – Tino
Devo essere in disaccordo abbastanza strenuamente. L'importazione/inclusione/utilizzo ha una lunga storia di utilizzo del modulo di riferimento e non della forma del valore in nust su ogni altra lingua. –
Dannazione, colpisco il ritorno ... c'è un'aspettativa di importazione per riferimento (come per @OP). In effetti, un nuovo programmatore Python, a prescindere da quanto esperto, deve essere raccontato in questo modo "guarda fuori". Questo non dovrebbe mai accadere: basato su un uso comune, Python ha preso la strada sbagliata. Creare un "valore di importazione" se necessario, ma non confondere simboli con valori al momento dell'importazione. –