Denken Sie zunächst daran, dass ein Modul in seiner genauen Definition ein Objekt im Speicher eines Python-Interpreters ist, das häufig durch Lesen einer oder mehrerer Dateien von der Festplatte erstellt wird. Während wir eine Datenträgerdatei wie a/b/c.py
ein "Modul" informell aufrufen können , wird sie erst dann zu einer, wenn sie mit Informationen aus mehreren anderen Quellen (z. B. sys.path
) kombiniert wird , um das Modulobjekt zu erstellen.
(Beachten Sie beispielsweise, dass zwei Module mit unterschiedlichen Namen abhängig von sys.path
und anderen Einstellungen aus derselben Datei geladen werden können. Genau dies geschieht mit python -m my.module
einem import my.module
im Interpreter gefolgt von einem ; es werden zwei Modulobjekte erstellt __main__
und my.module
beide erstellt aus derselben Datei auf der Festplatte , my/module.py
.)
Ein Paket ist ein Modul, das Submodule (einschließlich Subpakete) enthalten kann. Dies können nicht alle Module. Erstellen Sie als Beispiel eine kleine Modulhierarchie:
$ mkdir -p a/b
$ touch a/b/c.py
Stellen Sie sicher, dass sich keine anderen Dateien unter befinden a
. Starten Sie einen Python 3.4- oder späteren Interpreter (z. B. mit python3 -i
) und überprüfen Sie die Ergebnisse der folgenden Anweisungen:
import a
a ⇒ <module 'a' (namespace)>
a.b ⇒ AttributeError: module 'a' has no attribute 'b'
import a.b.c
a.b ⇒ <module 'a.b' (namespace)>
a.b.c ⇒ <module 'a.b.c' from '/home/cjs/a/b/c.py'>
Module a
und a.b
sind Pakete (in der Tat eine bestimmte Art von Paket, das als "Namespace-Paket" bezeichnet wird, obwohl wir uns hier nicht darum kümmern müssen). Das Modul a.b.c
ist jedoch kein Paket. Wir können dies demonstrieren, indem wir a/b.py
der obigen Verzeichnisstruktur eine weitere Datei hinzufügen und einen neuen Interpreter starten:
import a.b.c
⇒ ImportError: No module named 'a.b.c'; 'a.b' is not a package
import a.b
a ⇒ <module 'a' (namespace)>
a.__path__ ⇒ _NamespacePath(['/.../a'])
a.b ⇒ <module 'a.b' from '/home/cjs/tmp/a/b.py'>
a.b.__path__ ⇒ AttributeError: 'module' object has no attribute '__path__'
Python stellt sicher, dass alle übergeordneten Module geladen werden, bevor ein untergeordnetes Modul geladen wird. Darüber , dass findet a/
ein Verzeichnis ist , und schafft so ein Namespace - Paket a
, und das a/b.py
ist eine Datei Python Quelle , die es lädt und verwendet ein (nicht-Paket) Modul zu erstellen a.b
. Zu diesem Zeitpunkt können Sie kein Modul haben, a.b.c
da a.b
es sich nicht um ein Paket handelt und daher keine Submodule haben können.
Sie können hier auch sehen, dass das Paketmodul a
ein __path__
Attribut hat (Pakete müssen dieses haben), das Nicht-Paketmodul a.b
jedoch nicht.