Wahrscheinlich haben Sie bereits verstanden, dass der Interpreter beim Importieren eines Moduls einen neuen Namespace erstellt und den Code dieses Moduls mit dem neuen Namespace als lokalen und globalen Namespace ausführt. Wenn der Code die Ausführung abschließt, wird der Modulname (oder der in einer beliebigen as
-Klausel angegebene Name) an das gerade im importierenden Namespace erstellte Modulobjekt gebunden.
Die __init__.py
in einem Paket dient weitgehend die gleiche Funktion. Ein Paket mit Struktur wird als ein Verzeichnis geschrieben, das auch Module (reguläre .py
Dateien) und Unterverzeichnisse (die auch eine __init__.py
Datei enthalten müssen) für beliebige Unterpakete enthält. Wenn das Paket importiert wird, wird ein neuer Namespace erstellt, und __init__.py
des Pakets wird mit diesem Namespace als lokaler und globaler Namespace ausgeführt. Um Ihr Problem zu lösen, können wir Ihren Dateispeicher entfernen, indem Sie das Paket der obersten Ebene weglassen, das vom Interpreter nie berücksichtigt wird, wenn test.py
als Programm ausgeführt wird. Es würde dann wie folgt aussehen:
test.py
subpackage/
__init__.py
hello_world.py
Nun subpackage
ist nicht länger ein Unterpaket, wie wir das Paket enthält, als irrelevant entfernt haben. Konzentrieren Sie sich darauf, warum der Name do_something
nicht definiert ist. test.py
enthält keinen Import, und daher ist unklar, wie Sie erwarten, do_something
Bedeutung zu erwerben. Man könnte es mit Hilfe eines leeren subpackage/__init__.py
funktioniert und test.py
könnte dann lesen Sie
from subpackage.hello_world import do_something
do_something()
Alternativ könnte uns ein subpackage/__init__.py
die
from hello_world import do_something
liest, die die do_something
Funktion innerhalb des subpackage
Namensraum einrichtet, wenn das Paket importiert.Dann ein test.py
verwenden, die die Funktion aus dem Paket importiert, wie folgt aus:
from subpackage import do_something
do_something()
Eine letzte Alternative mit den gleichen __init__.py
ist ein test.py
zu verwenden, die einfach importiert das (sub) Paket und dann relativ Namensgebung verwenden, um den Zugriff auf gewünschte Funktion:
import subpackage
subpackage.do_something()
in Ihrem lokalen Namespace den Zugriff darauf zu gewinnen
mit dem leeren __init__.py
Dies könnte auch mit einem test.py
rea erreicht werden
ding
import subpackage.hello_world
subpackage.hello_world.do_something()
oder sogar
from subpackage.hello_world import do_something
do_something()
letztlich das beste Werkzeug, das Sie gerade zu halten ist ein klares Verständnis davon, wie Import funktioniert und was Wirkung seinen verschiedenen Formen auf dem Import Namespace haben.
Ich nehme an, das 'test.py', das Sie ausführen, ist' package/test.py'? Wenn das der Fall ist, muss ich nicht sehen, dass es sich in einem Paket befindet, und so scheint 'package/__ init __. Py' völlig irrelevant zu sein. – holdenweb