Was ist der Unterschied zwischen einem Python-Modul und einem Python-Paket?
Siehe auch: Was ist der Unterschied zwischen "Paket" und "Modul"? (für andere Sprachen)
Was ist der Unterschied zwischen einem Python-Modul und einem Python-Paket?
Siehe auch: Was ist der Unterschied zwischen "Paket" und "Modul"? (für andere Sprachen)
Jede Python-Datei ist eine Modul , wobei der Name der Basisname der Datei ohne den Zusatz .py
Erweiterung. A Paket ist eine Sammlung von Python-Modulen: Während ein Modul eine einzelne Python-Datei ist, ist ein Paket ein Verzeichnis von Python-Modulen, das eine zusätzliche __init__.py
Datei, um ein Paket von einem Verzeichnis zu unterscheiden, das nur zufällig eine Reihe von Python-Skripten enthält. Pakete können in beliebiger Tiefe verschachtelt werden, vorausgesetzt, die entsprechenden Verzeichnisse enthalten ihre eigenen __init__.py
Datei.
Die Unterscheidung zwischen Modul und Paket scheint nur auf der Ebene des Dateisystems zu gelten. Wenn Sie ein Modul oder ein Paket importieren, ist das entsprechende von Python erzeugte Objekt immer vom Typ module
. Beachten Sie jedoch, dass beim Import eines Pakets nur die Variablen/Funktionen/Klassen im __init__.py
Datei des Pakets direkt sichtbar sind, no Unterpaketen oder Modulen. Ein Beispiel hierfür ist das xml
Paket in der Python-Standardbibliothek: sein xml
Verzeichnis enthält eine __init__.py
Datei und vier Unterverzeichnisse; das Unterverzeichnis etree
enthält eine __init__.py
Datei und, unter anderem, eine ElementTree.py
Datei. Sehen Sie, was passiert, wenn Sie versuchen, interaktiv Pakete/Module zu importieren:
>>> import xml
>>> type(xml)
<type 'module'>
>>> xml.etree.ElementTree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'etree'
>>> import xml.etree
>>> type(xml.etree)
<type 'module'>
>>> xml.etree.ElementTree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'ElementTree'
>>> import xml.etree.ElementTree
>>> type(xml.etree.ElementTree)
<type 'module'>
>>> xml.etree.ElementTree.parse
<function parse at 0x00B135B0>
In Python gibt es auch eingebaute Module, wie z.B. sys
, die in C geschrieben sind, aber ich glaube nicht, dass Sie diese in Ihrer Frage berücksichtigen wollten.
Erstens ist zu bedenken, dass nach der genauen Definition ein Modul ist ein Objekt im Speicher eines Python-Interpreters, das oft durch Lesen einer oder mehrerer Dateien von der Festplatte erzeugt wird. Während wir eine Festplattendatei informell wie folgt nennen können a/b/c.py
ein "Modul" ist, wird es erst dann zu einem solchen, wenn es mit Informationen aus mehreren anderen Quellen kombiniert wird (z. B. sys.path
), um das Modulobjekt zu erstellen.
(Beachten Sie zum Beispiel, dass zwei Module mit unterschiedlichen Namen aus derselben Datei geladen werden können, abhängig von sys.path
und andere Einstellungen. Genau dies geschieht mit python -m my.module
gefolgt von einer import my.module
im Interpreter; es wird zwei Modulobjekte geben, __main__
y my.module
, die beide aus derselben Datei auf der Festplatte erstellt wurden, my/module.py
.)
A Paket ist ein Modul, das Untermodule (einschließlich Unterpakete) haben kann. Nicht alle Module können dies tun. Erstellen Sie als Beispiel eine kleine Modulhierarchie:
$ mkdir -p a/b
$ touch a/b/c.py
Vergewissern Sie sich, dass sich keine anderen Dateien unter a
. Starten Sie einen Python 3.4 oder höher Interpreter (z.B. mit python3 -i
) und untersuchen Sie die Ergebnisse der folgenden Aussagen:
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
y a.b
sind Pakete (eigentlich eine bestimmte Art von Paketen, die "Namespace-Pakete" genannt werden, aber darum werden wir uns hier nicht kümmern). Allerdings, Modul a.b.c
ist kein Paket. Wir können dies demonstrieren, indem wir eine weitere Datei hinzufügen, a/b.py
in die obige Verzeichnisstruktur einfü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. Oben findet es, dass a/
ist ein Verzeichnis und erzeugt daher ein Namensraumpaket a
und dass a/b.py
ist eine Python-Quelldatei, die er lädt und verwendet, um ein (Nicht-Paket-)Modul zu erstellen a.b
. Zu diesem Zeitpunkt können Sie kein Modul haben a.b.c
denn a.b
ist kein Paket und kann daher keine Untermodule haben.
Sie können hier auch sehen, dass das Paketmodul a
hat eine __path__
Attribut (Pakete müssen dies haben), aber das Nicht-Paketmodul a.b
nicht.
Von der Python-Glossar :
Es ist wichtig zu wissen, dass alle Pakete Module sind, aber nicht alle Module sind Pakete. Oder anders ausgedrückt: Pakete sind nur eine spezielle Art von Modulen. Genauer gesagt, jedes Modul, das ein
__path__
Attribut wird als Paket betrachtet.
Python-Dateien mit einem Bindestrich im Namen, wie my-file.py
kann nicht mit einer einfachen import
Erklärung. Code-mäßig, import my-file
ist dasselbe wie import my - file
was eine Ausnahme auslöst. Solche Dateien sind besser charakterisiert als Skripte während importierbare Dateien sind Module .
Die anderen Antworten hier sind vielleicht noch etwas vage, deshalb gebe ich eine hoffentlich klarere Antwort. Es ist wichtig anzumerken, dass der Titel der Frage auch ein wenig irreführend ist, und ein besserer Titel wäre meiner Meinung nach: " Was ist das Besondere an Paketmodulen im Vergleich zu normalen Modulen? " .
Auch Pakete sind Module, sie sind jedoch eine besondere Art von Modulen. Speziell in dem Sinne, dass 1. sie sind "Verzeichnisse" und 2. können sie spezielle Dateien enthalten, wie z.B. __init__.py
y __main__.py
.
Der Punkt ist, Pakete sind eine besondere Art von Modulen Wir müssen also verstehen Module im Allgemeinen und dann wird auch klar, was das Besondere an den Paketmodulen ist. (Beachte: Ich werde in dieser Antwort manchmal von "Paketmodulen" sprechen und umgekehrt)
Lassen Sie uns also zunächst über Module im Allgemeinen sprechen, da dies weniger vage und leichter zu verstehen ist. Es gibt grundsätzlich zwei Möglichkeiten, mit Modulen umzugehen: Entweder wir importieren sie in andere Module oder wir führen sie direkt mit Python aus.
Der Import eines Moduls hat ein einziges offensichtliches Ziel: den Zugriff auf die Inhalte des Moduls.
Mit der Ausführung eines Moduls wird jedoch in der Regel eines dieser beiden Ziele verfolgt:
Lassen Sie uns all dies anhand einiger Beispiele näher erläutern:
# bar.py
def talk():
print("bar")
# foo.py
import bar # <-- importing module "bar"
bar.talk() # <-- prints "bar"
Gehen wir davon aus, dass die foo.py
Modul im obigen Beispiel ist ein Hauptmodul, das unser Programm startet. Wir können es ausführen, indem wir diesen Befehl in das Terminal eingeben: python3 foo.py # <-- executing a main module
und dann wird unser Programm gestartet.
Nehmen wir an, wir wollen die Funktion talk
im bar.py
im obigen Beispiel, ohne unser gesamtes Programm auszuführen, d. h. ohne das Modul foo.py
. Hierfür müssen wir die bar.py
:
# bar.py
def talk():
print("bar")
if __name__ == '__main__':
talk()
Führen Sie nun diesen Befehl im Terminal aus: python3 bar.py # <-- trying functionalities of a module in isolation
und dann wird gedruckt bar
.
Da wir nun wissen, was wir mit Modulen im Allgemeinen tun können, wollen wir zur Hauptfrage zurückkehren:
__init__.py
Datei in seinem Verzeichnis, und wenn Sie ein Paketmodul "ausführen" wollen, müssen Sie den Ausführungscode des Moduls in eine __main__.py
Datei in ihrem Verzeichnis.Und hier ist das letzte Beispiel für die obige Erklärung:
# hierarchy of files and folders:
.
bar_pack/
__init__.py
__main__.py
foo.py
# bar_pack/__init__.py
def talk():
print("bar")
# bar_pack/__main__.py
import __init__
__init__.talk()
# foo.py
import bar_pack # <-- importing package module "bar_pack"
bar_pack.talk() # <-- prints "bar"
# Run this command in the terminal:
python3 bar_pack # <-- executing the package module "bar_pack", prints "bar"
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.