Probabilmente già comprendi che quando si importa un modulo , l'interprete crea un nuovo spazio dei nomi ed esegue il codice di quel modulo con il nuovo spazio dei nomi come spazio dei nomi locale e globale. Quando il codice completa l'esecuzione, il nome del modulo (o il nome dato in qualsiasi clausola as
) è associato all'oggetto modulo appena creato all'interno dello spazio dei nomi di importazione.
Lo __init__.py
in un pacchetto ha la stessa funzione. Un pacchetto , con struttura, è scritto come una directory che può contenere anche moduli (file regolari .py
) e sottodirectory (che deve contenere anche un file __init__.py
) per qualsiasi sotto_package. Quando il pacchetto viene importato, viene creato un nuovo spazio dei nomi e il pacchetto __init__.py
viene eseguito con tale spazio dei nomi come spazi dei nomi locali e globali. Pertanto, per rispondere al problema, è possibile eliminare il file archivio omettendo il pacchetto di livello superiore, che non verrà mai preso in considerazione dall'interprete quando test.py
viene eseguito come programma. Sarebbe quindi simile a questa:
test.py
subpackage/
__init__.py
hello_world.py
Ora, subpackage
non è più un sub-pacchetto, come abbiamo rimosso il pacchetto contenente come irrilevante. Concentrarsi sul perché il nome do_something
non è definito potrebbe aiutare. test.py
non contiene alcuna importazione, quindi non è chiaro come ti aspetti che do_something
acquisisca un significato. Si potrebbe farlo funzionare utilizzando un vuoto subpackage/__init__.py
e poi test.py
potrebbe leggere
from subpackage.hello_world import do_something
do_something()
In alternativa si potrebbe noi una subpackage/__init__.py
che legge
from hello_world import do_something
che stabilisce la funzione do_something
all'interno della subpackage
spazio dei nomi quando il pacchetto è importato.Quindi utilizzare un test.py
che importa la funzione dal pacchetto, in questo modo:
from subpackage import do_something
do_something()
Un'alternativa finale con la stessa __init__.py
è usare un test.py
che importa semplicemente il pacchetto (sub) e quindi usare relativa denominazione per accedere funzione richiesta:
import subpackage
subpackage.do_something()
per ottenere l'accesso ad esso nello spazio dei nomi locale
con il vuoto __init__.py
questo potrebbe anche essere realizzato con un test.py
rea ding
import subpackage.hello_world
subpackage.hello_world.do_something()
o anche
from subpackage.hello_world import do_something
do_something()
In definitiva lo strumento migliore per tenervi retta è una chiara comprensione di come funziona importazione e che effetto le sue varie forme hanno sul namespace importazione.
Suppongo che 'test.py' sia in esecuzione' package/test.py'? Se è così, non c'è bisogno che io possa vedere perché si trovi in un pacchetto, e quindi 'package/__ init __. Py' sembrerebbe del tutto irrilevante. – holdenweb