837 Stimmen

Was ist der Unterschied zwischen einem Python-Modul und einem Python-Paket?

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)

783voto

Giulio Piancastelli Punkte 14438

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.

451voto

Jakob Bowyer Punkte 32375

Ein Modul ist eine einzelne Datei (oder mehrere Dateien), die unter einem Import importiert und verwendet werden. z.B.

import my_module

Ein Paket ist eine Sammlung von Modulen in Verzeichnissen, die eine Pakethierarchie bilden.

from my_package.timing.danger.internets import function_of_love

Dokumentation für Module

Einführung in die Pakete

70voto

cjs Punkte 23476

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.

44voto

jolvi Punkte 3935

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 .

21voto

aderchox Punkte 1534

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? " .

TL;DR - Kurze Antwort:

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 .

Zum besseren Verständnis - Längere Antwort:

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:

  1. Dieses Modul ist ein Hauptmodul und seine Ausführung wird unser Programm (oder eines seiner Unterprogramme) starten.
  2. Wir wollen die Funktionen dieses Moduls isoliert ausprobieren, d. h. ohne es vorher importieren zu müssen.

Lassen Sie uns all dies anhand einiger Beispiele näher erläutern:

Module importieren:

# bar.py

def talk():
    print("bar")

# foo.py

import bar # <-- importing module "bar"

bar.talk() # <-- prints "bar"

Ausführen von Modulen

Ziel 1, die Ausführung eines Moduls als Hauptmodul:

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.

Ziel 2, die Funktionalitäten eines Moduls isoliert zu testen:

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:

Was ist das Besondere an Paketmodulen im Vergleich zu normalen Modulen?

1. Normale Module in Python sind einfach "Dateien", Paketmodule sind jedoch "Verzeichnisse".

2. Reguläre Module können "importiert" und "ausgeführt" werden (wie in den obigen Beispielen gezeigt), Paketmodule können AUCH "importiert" und "ausgeführt" werden, WIE auch immer, Sie können sich zu Recht beschweren: " aber wir können keinen Code direkt in Verzeichnisse schreiben! Code wird nur in Dateien geschrieben!" und das ist in der Tat eine sehr gute Beschwerde, denn sie führt uns zu der zweiten Besonderheit von Paketmodulen. Der Code für ein Paketmodul wird in Dateien innerhalb seines Verzeichnisses und die Namen dieser Dateien sind ebenfalls von Python reserviert. Wenn Sie ein Paketmodul "importieren" wollen, müssen Sie seinen Code in eine __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.com

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.

Powered by:

X