6. Module
*********

Wenn Sie den Python-Interpreter beenden und erneut starten, gehen die
von dir erstellten Definitionen (Funktionen und Variablen) verloren.
Wenn du also ein etwas längeres Programm schreiben möchtest, solltest
du die Eingabe für den Interpreter besser in einem Texteditor
vorbereiten und den Interpreter stattdessen mit dieser Datei als
Eingabe ausführen.  Dies wird als Erstellen eines *Skripts*
bezeichnet. Wenn dein Programm länger wird, möchtes du es
möglicherweise zur einfacheren Wartung in mehrere Dateien aufteilen.
Vielleicht möchtest du auch eine nützliche Funktion, die du
geschrieben hast, in mehreren Programmen verwenden, ohne deren
Definition in jedes Programm kopieren zu müssen.

Um dies zu unterstützen, bietet Python die Möglichkeit, Definitionen
in einer Datei zu speichern und sie in einem Skript oder in einer
interaktiven Instanz des Interpreters zu verwenden. Eine solche Datei
wird als *Modul* bezeichnet; Definitionen aus einem Modul können in
andere Module oder in das *Hauptmodul* (*main*) *importiert* werden
(die Sammlung von Variablen, auf die du in einem Skript auf oberster
Ebene und im Taschenrechnermodus Zugriff hast).

Ein Modul ist eine Datei, die Python-Definitionen und -Anweisungen
enthält. Der Dateiname besteht aus dem Modulnamen mit dem angehängten
Suffix ".py".  Innerhalb eines Moduls steht der Modulname (als
Zeichenkette) als Wert der globalen Variablen "__name__" zur
Verfügung.  Erstelle beispielsweise mit deinem bevorzugten Texteditor
im aktuellen Verzeichnis eine Datei namens "fibo.py" mit folgendem
Inhalt:

   # Modul „Fibonacci-Zahlen“

   def fib(n):
       """Die Fibonacci-Folge bis n ausgeben."""
       a, b = 0, 1
       while a < n:
           print(a, end=' ')
           a, b = b, a+b
       print()

   def fib2(n):
       """Gibt die Fibonacci-Folge bis n zurück."""
       result = []
       a, b = 0, 1
       while a < n:
           result.append(a)
           a, b = b, a+b
       return result

Öffne nun den Python-Interpreter und importiere dieses Modul mit dem
folgenden Befehl:

   >>> import fibo

Dadurch werden die Namen der in "fibo" definierten Funktionen nicht
direkt zum aktuellen *Namensraum* hinzugefügt (weitere Details finden
Sie unter Python-Gültigkeitsbereiche und Namensräume ); es wird dort
lediglich der Modulname "fibo" hinzugefügt. Über den Modulnamen kannst
du auf die Funktionen zugreifen:

   >>> fibo.fib(1000)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
   >>> fibo.fib2(100)
   [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
   >>> fibo.__name__
   'fibo'

Wenn du eine Funktion häufig verwenden möchtest, kannst du ihr einen
lokalen Namen zuweisen:

   >>> fib = fibo.fib
   >>> fib(500)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377


6.1. Mehr zum Thema Module
==========================

Ein Modul kann sowohl ausführbare Anweisungen als auch
Funktionsdefinitionen enthalten. Diese Anweisungen dienen der
Initialisierung des Moduls. Sie werden nur beim *ersten* Auftreten des
Modulnamens in einer Importanweisung ausgeführt. [1] (Sie werden auch
ausgeführt, wenn die Datei als Skript ausgeführt wird.)

Jedes Modul verfügt über einen eigenen privaten Namensraum, der von
allen im Modul definierten Funktionen als globaler Namensraum genutzt
wird. Somit kann der Autor eines Moduls globale Variablen im Modul
verwenden, ohne sich Gedanken über versehentliche Konflikte mit den
globalen Variablen eines Benutzers machen zu müssen. Andererseits
kannst du, wenn du weisst, was du tust, auf die globalen Variablen
eines Moduls mit derselben Notation zugreifen, die auch für den
Verweis auf dessen Funktionen verwendet wird:"modname.itemname`".

Module können andere Module importieren. Es ist üblich, aber nicht
zwingend erforderlich, alle "import"-Anweisungen am Anfang eines
Moduls (oder Skripts) zu platzieren. Die Namen der importierten Module
werden, sofern sie auf der obersten Ebene eines Moduls (außerhalb von
Funktionen oder Klassen) stehen, dem globalen Namensraum des Moduls
hinzugefügt.

Es gibt eine Variante der Anweisung "import", mit der Namen aus einem
Modul direkt in den Namensraum des importierenden Moduls importiert
werden. Zum Beispiel:

   >>> from fibo import fib, fib2
   >>> fib(500)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Dadurch wird der Modulname, aus dem die Importe stammen, nicht in den
lokalen Namensraum eingeführt (im Beispiel ist "fibo" also nicht
definiert).

Es gibt sogar eine Variante, mit der alle von einem Modul definierten
Namen importiert werden können:

   >>> from fibo import *
   >>> fib(500)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Dadurch werden alle Namen importiert, mit Ausnahme derjenigen, die mit
einem Unterstrich beginnen ("_"). In den meisten Fällen nutzen Python-
Programmierer diese Funktion nicht, da dadurch eine unbekannte Menge
von Namen in den Interpreter eingeführt wird, wodurch möglicherweise
einige bereits von dir definierte Elemente verdeckt werden.

Beachte, dass das Importieren von "*" aus einem Modul oder Paket im
Allgemeinen nicht gerne gesehen wird, da dies oft zu schwer lesbarem
Code führt. Es ist jedoch in Ordnung, diese Funktion zu verwenden, um
sich in interaktiven Sitzungen Tipparbeit zu ersparen.

Folgt auf den Modulnamen "as" “, wird der Name nach "as" direkt an das
importierte Modul gebunden.

   >>> import fibo as fib
   >>> fib.fib(500)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Damit wird das Modul im Grunde genauso importiert wie mit dem Befehl
"import fibo" “, mit dem einzigen Unterschied, dass es unter "fib"
verfügbar ist.

Es kann auch bei der Verwendung von "from" mit ähnlichen Effekten
eingesetzt werden:

   >>> from fibo import fib as fibonacci
   >>> fibonacci(500)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Bemerkung:

  Aus Effizienzgründen wird jedes Modul pro Interpreter-Sitzung nur
  einmal geladen. Wenn du also Ihre Module änderst, musst du den
  Interpreter neu starten – oder, falls du nur ein Modul interaktiv
  testen möchten, die Funktion "importlib.reload()" verwenden, z. B.
  "import importlib; importlib.reload(modulename)".


6.1.1. Module als Skripte ausführen
-----------------------------------

Wenn du ein Python-Modul mit :: ausführst:

   python fibo.py <arguments>

Der Code im Modul wird ausgeführt, genau so, als hättest du ihn
importiert, allerdings mit der Einstellung "__name__" auf ""__main__""
. Das bedeutet, dass du durch Hinzufügen dieses Codes am Ende deines
Moduls:

   if __name__ == "__main__":
       import sys
       fib(int(sys.argv[1]))

Du kannst die Datei sowohl als Skript als auch als importierbares
Modul nutzen, da der Code, der die Befehlszeile auswertet, nur
ausgeführt wird, wenn das Modul als "Hauptdatei" ausgeführt wird:

   $ python fibo.py 50
   0 1 1 2 3 5 8 13 21 34

Wenn das Modul importiert wird, wird der Code nicht ausgeführt:

   >>> import fibo
   >>>

Dies wird häufig entweder verwendet, um eine benutzerfreundliche
Oberfläche für ein Modul bereitzustellen, oder zu Testzwecken (die
Ausführung des Moduls als Skript führt eine Testsuite aus).


6.1.2. Der Suchpfad für Module
------------------------------

Wenn ein Modul namens "spam" importiert wird, sucht der Interpreter
zunächst nach einem integrierten Modul mit diesem Namen. Diese
Modulnamen sind unter "sys.builtin_module_names" aufgeführt. Wird es
dort nicht gefunden, sucht er anschließend nach einer Datei namens
"spam.py" in einer Liste von Verzeichnissen, die durch die Variable
"sys.path" angegeben wird. "sys.path" wird anhand dieser Speicherorte
initialisiert:

* Das Verzeichnis, in dem sich das Eingabeskript befindet (oder das
  aktuelle Verzeichnis, wenn keine Datei angegeben ist).

* "PYTHONPATH" (eine Liste von Verzeichnisnamen, deren Syntax der der
  Shell-Variablen "PATH" entspricht).

* Die installationsabhängige Standardeinstellung (gemäß Konvention
  einschließlich des Verzeichnisses "site-packages"  , das vom Modul
  "site" verwaltet wird).

Weitere Informationen findest du unter The initialization of the
sys.path module search path.

Bemerkung:

  Bei Dateisystemen, die symbolische Links unterstützen, wird das
  Verzeichnis, in dem sich das Eingabeskript befindet, erst ermittelt,
  nachdem dem symbolischen Link gefolgt wurde. Mit anderen Worten: Das
  Verzeichnis, in dem sich der symbolische Link befindet, wird
  **nicht** zum Suchpfad des Moduls hinzugefügt.

Nach der Initialisierung können Python-Programme die Variable
"sys.path" ändern. Das Verzeichnis, in dem sich das ausgeführte Skript
befindet, wird an den Anfang des Suchpfads gesetzt, noch vor dem
Standardbibliothekspfad. Das bedeutet, dass Skripte in diesem
Verzeichnis anstelle von Modulen mit demselben Namen im
Bibliotheksverzeichnis geladen werden. Dies führt zu einem Fehler, es
sei denn, die Ersetzung ist beabsichtigt. Weitere Informationen
findest du im Abschnitt Standardmodule .


6.1.3. "Kompilierte" Python-Dateien
-----------------------------------

Um das Laden von Modulen zu beschleunigen, speichert Python die
kompilierte Version jedes Moduls im Verzeichnis "__pycache__" unter
dem Namen "module.*version*.pyc", wobei die Versionsangabe das Format
der kompilierten Datei angibt; sie enthält in der Regel die Python-
Versionsnummer.  Beispielsweise würde in der CPython-Version 3.3 die
kompilierte Version von spam.py als "__pycache__/spam.cpython-33.pyc"
zwischengespeichert werden. Diese Namenskonvention ermöglicht es, dass
kompilierte Module aus verschiedenen Releases und verschiedenen
Python-Versionen nebeneinander existieren können.

Python vergleicht das Änderungsdatum der Quelldatei mit der
kompilierten Version, um festzustellen, ob diese veraltet ist und neu
kompiliert werden muss. Dies ist ein vollständig automatischer
Vorgang. Außerdem sind die kompilierten Module plattformunabhängig,
sodass dieselbe Bibliothek auf Systemen mit unterschiedlichen
Architekturen gemeinsam genutzt werden kann.

Python überprüft den Cache unter zwei Umständen nicht. Erstens wird
das Modul, das direkt über die Befehlszeile geladen wird, immer neu
kompiliert, und das Ergebnis wird nicht gespeichert.  Zweitens wird
der Cache nicht überprüft, wenn kein Quellmodul vorhanden ist.  Um
eine Distribution ohne Quellcode (nur kompiliert) zu unterstützen,
muss sich das kompilierte Modul im Quellverzeichnis befinden, und es
darf kein Quellmodul vorhanden sein.

Einige Tipps für Experten:

* Sie können die Schalter "-O" oder "-OO" im Python-Befehl verwenden,
  um die Größe eines kompilierten Moduls zu verringern. Der Schalter
  "-O" entfernt "assert"-Anweisungen, der Schalter "-OO" entfernt
  sowohl "assert"-Anweisungen als auch "__doc__"-Zeichenketten. Da
  manche Programme möglicherweise darauf angewiesen sind, dass diese
  verfügbar sind, solltest du diese Option nur verwenden, wenn du
  genau weisst, was du tust.  "Optimierte" Module tragen das Tag
  "opt-" und sind in der Regel kleiner. In zukünftigen Versionen
  können sich die Auswirkungen der Optimierung ändern.

* Ein Programm läuft nicht schneller, wenn es aus einer ".pyc" -Datei
  geladen wird, als wenn es aus einer ".py" -Datei geladen wird; das
  Einzige, was bei ".pyc" -Dateien schneller ist, ist die
  Geschwindigkeit, mit der sie geladen werden.

* Das Modul "compileall" kann für alle Module in einem Verzeichnis
  .pyc-Dateien erstellen.

* Weitere Einzelheiten zu diesem Prozess, einschließlich eines
  Entscheidungsdiagramms, findest du unter **PEP 3147**.


6.2. Standardmodule
===================

Python verfügt über eine Bibliothek mit Standardmodulen, die in einem
separaten Dokument, der Python-Bibliotheksreferenz (im Folgenden
"Bibliotheksreferenz"), beschrieben sind.  Einige Module sind in den
Interpreter integriert; diese bieten Zugriff auf Operationen, die zwar
nicht zum Kern der Sprache gehören, aber dennoch integriert sind –
entweder aus Gründen der Effizienz oder um Zugriff auf
Betriebssystemprimitive wie Systemaufrufe zu ermöglichen.  Die Auswahl
dieser Module ist eine Konfigurationsoption, die zudem von der
zugrunde liegenden Plattform abhängt.  Beispielsweise wird das Modul
"winreg" nur auf Windows-Systemen bereitgestellt. Ein bestimmtes Modul
verdient besondere Beachtung:  "sys", das in jeden Python-Interpreter
integriert ist. Die Variablen "sys.ps1" und "sys.ps2" definieren die
Zeichenketten, die als primäre und sekundäre Eingabeaufforderung
verwendet werden:

   >>> import sys
   >>> sys.ps1
   '>>> '
   >>> sys.ps2
   '... '
   >>> sys.ps1 = 'C> '
   C> print('Igitt!')
   Igitt!
   C>

Diese beiden Variablen sind nur definiert, wenn sich der Interpreter
im interaktiven Modus befindet.

Die Variable "sys.path" ist eine Liste von Zeichenketten, die den
Suchpfad des Interpreters für Module festlegt. Sie wird mit einem
Standardpfad initialisiert, der aus der Umgebungsvariable "PYTHONPATH"
übernommen wird, oder – falls "PYTHONPATH"  nicht gesetzt ist – mit
einem integrierten Standardwert. Sie können sie mithilfe von
Standardoperationen für Listen ändern:

   >>> import sys
   >>> sys.path.append('/ufs/guido/lib/python')


6.3. Die Funktion "dir()"
=========================

Die integrierte Funktion "dir()" dient dazu, herauszufinden, welche
Namen ein Modul definiert. Sie gibt eine sortierte Liste von
Zeichenketten zurück:

   >>> import fibo, sys
   >>> dir(fibo)
   ['__name__', 'fib', 'fib2']
   >>> dir(sys)
   ['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__',
    '__interactivehook__', '__loader__', '__name__', '__package__', '__spec__',
    '__stderr__', '__stdin__', '__stdout__', '__unraisablehook__',
    '_clear_type_cache', '_current_frames', '_debugmallocstats', '_framework',
    '_getframe', '_git', '_home', '_xoptions', 'abiflags', 'addaudithook',
    'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix',
    'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing',
    'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info',
    'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info',
    'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth',
    'getallocatedblocks', 'getdefaultencoding', 'getdlopenflags',
    'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile',
    'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval',
    'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
    'intern', 'is_finalizing', 'last_traceback', 'last_type', 'last_value',
    'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks',
    'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'pycache_prefix',
    'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth', 'setdlopenflags',
    'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr',
    'stdin', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info',
    'warnoptions']

Ohne Argumente listet der Befehl "dir()" die Namen auf, die du derzeit
definiert hast:

   >>> a = [1, 2, 3, 4, 5]
   >>> import fibo
   >>> fib = fibo.fib
   >>> dir()
   ['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']

Beachte, dass hier alle Arten von Namen aufgeführt sind: Variablen,
Module, Funktionen usw.

"dir()" enthält keine Auflistung der Namen der integrierten Funktionen
und Variablen.  Wenn du eine Liste davon benötigst: Diese sind im
Standardmodul "builtins" definiert

   >>> import builtins
   >>> dir(builtins)
   ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',
    'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning',
    'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError',
    'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',
    'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
    'FileExistsError', 'FileNotFoundError', 'FloatingPointError',
    'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError',
    'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError',
    'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError',
    'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented',
    'NotImplementedError', 'OSError', 'OverflowError',
    'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError',
    'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',
    'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
    'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',
    'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',
    'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
    'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__',
    '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs',
    'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable',
    'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits',
    'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit',
    'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr',
    'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass',
    'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview',
    'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property',
    'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice',
    'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars',
    'zip']


6.4. Pakete
===========

Pakete sind eine Möglichkeit, den Modul-Namensraum von Python mithilfe
von "Modulnamen mit Punkt" zu strukturieren. Der Modulname "A.B"
bezeichnet beispielsweise ein Untermodul namens "B" in einem Paket
namens "A" .  Genauso wie die Verwendung von Modulen den Autoren
verschiedener Module erspart, sich um die globalen Variablennamen der
anderen kümmern zu müssen, erspart die Verwendung von Modulnamen mit
Punkten den Autoren von Paketen mit mehreren Modulen wie NumPy oder
Pillow, sich um die Modulnamen der anderen kümmern zu müssen.

Angenommen, du möchtest eine Sammlung von Modulen (ein „Paket“) für
die einheitliche Verarbeitung von Audiodateien und Audiodaten
entwerfen. Es gibt viele verschiedene Audiodateiformate (die in der
Regel an ihrer Dateiendung zu erkennen sind, zum Beispiel: ".wav",
".aiff", ".au"), sodass du möglicherweise eine ständig wachsende
Sammlung von Modulen für die Konvertierung zwischen den verschiedenen
Dateiformaten erstellen und pflegen musst. Außerdem gibt es viele
verschiedene Operationen, die du möglicherweise an Audiodaten
durchführen möchtest (wie Mischen, Hinzufügen eines Echos, Anwenden
einer Equalizer-Funktion, Erzeugen eines künstlichen Stereoeffekts),
sodass du darüber hinaus eine endlose Reihe von Modulen schreiben
wirst, um diese Operationen auszuführen.  Hier ist eine mögliche
Struktur für dein Paket (dargestellt als hierarchisches Dateisystem):

   sound/                          Paket der obersten Ebene
         __init__.py               Initialisierung des Sound-Pakets
         formats/                  Unterpaket für Dateiformatkonvertierungen
                 __init__.py
                 wavread.py
                 wavwrite.py
                 aiffread.py
                 aiffwrite.py
                 auread.py
                 auwrite.py
                 ...
         effects/                  Unterpaket für Soundeffekte
                 __init__.py
                 echo.py
                 surround.py
                 reverse.py
                 ...
         filters/                  Unterpaket für Filter
                 __init__.py
                 equalizer.py
                 vocoder.py
                 karaoke.py
                 ...

Beim Importieren des Pakets durchsucht Python die Verzeichnisse unter
"sys.path" nach dem Unterverzeichnis des Pakets.

Die "__init__.py"  -Dateien sind erforderlich, damit Python
Verzeichnisse, die diese Datei enthalten, als Pakete behandelt (es sei
denn, es wird ein *Namespace-Paket* verwendet, eine relativ
fortgeschrittene Funktion). Dies verhindert, dass Verzeichnisse mit
einem gemeinsamen Namen, wie beispielsweise "string"  , unbeabsichtigt
gültige Module verdecken, die später im Modulsuchpfad vorkommen. Im
einfachsten Fall kann "__init__.py" einfach eine leere Datei sein, sie
kann aber auch Initialisierungscode für das Paket ausführen oder die
Variable "__all__" setzen, die später beschrieben wird.

Benutzer des Pakets können einzelne Module aus dem Paket importieren,
zum Beispiel:

   import sound.effects.echo

Dadurch wird das Submodul "sound.effects.echo" geladen. Es muss mit
seinem vollständigen Namen referenziert werden.

   sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

Eine alternative Möglichkeit, das Submodul zu importieren, ist:

   from sound.effects import echo

Dadurch wird auch das Submodul "echo" geladen und ohne sein
Paketpräfix zur Verfügung gestellt, sodass es wie folgt verwendet
werden kann:

   echo.echofilter(input, output, delay=0.7, atten=4)

Eine weitere Möglichkeit besteht darin, die gewünschte Funktion oder
Variable direkt zu importieren:

   from sound.effects.echo import echofilter

Auch hier wird das Submodul "echo" geladen, wodurch dessen Funktion
"echofilter()" direkt verfügbar ist:

   echofilter(input, output, delay=0.7, atten=4)

Beachte dass bei der Verwendung von "from package import item"  das
Element entweder ein Submodul (oder Subpaket) des Pakets oder ein
anderer im Paket definierter Name sein kann, wie beispielsweise eine
Funktion, eine Klasse oder eine Variable. Die Anweisung "import" prüft
zunächst, ob das Element im Paket definiert ist; ist dies nicht der
Fall, geht sie davon aus, dass es sich um ein Modul handelt, und
versucht, dieses zu laden.  Wird das Element nicht gefunden, wird eine
Ausnahme vom Typ "ImportError" ausgelöst.

Im Gegensatz dazu muss bei der Verwendung einer Syntax wie "import
item.subitem.subsubitem" jedes Element mit Ausnahme des letzten ein
Paket sein; das letzte Element kann ein Modul oder ein Paket sein,
darf jedoch keine Klasse, Funktion oder Variable sein, die im
vorherigen Element definiert wurde.


6.4.1. Importieren von * aus einem Paket
----------------------------------------

Was passiert nun, wenn der Benutzer "from sound.effects import *"
eingibt? Im Idealfall würde man hoffen, dass dies irgendwie an das
Dateisystem weitergeleitet wird, das dann ermittelt, welche Submodule
im Paket vorhanden sind, und diese alle importiert. Dies könnte lange
dauern, und das Importieren von Submodulen könnte unerwünschte
Nebenwirkungen haben, die nur auftreten sollten, wenn das Submodul
explizit importiert wird.

Die einzige Lösung besteht darin, dass der Paketautor einen expliziten
Index des Pakets bereitstellt. Die Anweisung "import" verwendet die
folgende Konvention: Wenn im Code von "__init__.py" eines Pakets eine
Liste namens "__all__" definiert ist, wird diese als Liste der
Modulnamen angesehen, die importiert werden sollen, sobald auf "from
package import *" gestoßen wird.  Es liegt im Ermessen des
Paketautors, diese Liste bei der Veröffentlichung einer neuen Version
des Pakets auf dem neuesten Stand zu halten. Paketautoren können sich
auch dafür entscheiden, diese Funktion nicht zu unterstützen, wenn sie
keinen Nutzen darin sehen, * aus ihrem Paket zu importieren.
Beispielsweise könnte die Datei "sound/effects/__init__.py" den
folgenden Code enthalten:

   __all__ = ["echo", "surround", "reverse"]

Das würde bedeuten, dass "from sound.effects import *" die drei
genannten Submodule des Pakets "sound.effects" importieren würde.

Beachte, dass Submodule durch lokal definierte Namen überschattet
werden können. Wenn du beispielsweise die Funktion "reverse" zur Datei
"sound/effects/__init__.py" hinzugefügt hast, würde die Datei "from
sound.effects import *" nur die beiden Submodule "echo" und "surround"
importieren, jedoch *nicht* das Submodul "reverse"  , da dieses durch
die lokal definierte Funktion "reverse"   überschattet wird:

   __all__ = [
       "echo",      # bezieht sich auf die Datei „echo.py“
       "surround",  # bezieht sich auf die Datei „surround.py“
       "reverse",   # !!! bezieht sich jetzt auf die Funktion „reverse“ !!!
   ]

   def reverse(msg: str):  # <-- dieser Name überschreibt das Submodul „reverse.py“
       return msg[::-1]    #     im Fall von „from sound.effects import *“

Wenn "__all__" nicht definiert ist, importiert die Anweisung "from
sound.effects import *" *nicht* alle Submodule aus dem Paket
"sound.effects" in den aktuellen Namensraum; sie stellt lediglich
sicher, dass das Paket "sound.effects" importiert wurde (wobei
gegebenenfalls der Initialisierungscode in "__init__.py" ausgeführt
wird) und importiert anschließend alle Namen, die in diesem Paket
definiert sind.  Dazu gehören alle Namen, die von "__init__.py"
definiert wurden (sowie explizit geladene Submodule).  Ebenfalls
enthalten sind alle Submodule des Pakets, die durch vorherige "import"
-Anweisungen explizit geladen wurden.  Betrachte folgenden Code:

   import sound.effects.echo
   import sound.effects.surround
   from sound.effects import *

In diesem Beispiel werden die Module "echo" und "surround" in den
aktuellen Namensraum importiert, da sie im Paket "sound.effects"
definiert sind, wenn die Anweisung "from...import" ausgeführt wird.
(Dies funktioniert auch, wenn "__all__" definiert ist.)

Obwohl bestimmte Module so konzipiert sind, dass sie bei Verwendung
von "import *" nur Namen exportieren, die bestimmten Mustern
entsprechen, gilt dies im Produktionscode dennoch als schlechte
Praxis.

Denke daran: Es ist völlig in Ordnung, "from package import
specific_submodule"  zu verwenden! Tatsächlich ist dies die empfohlene
Schreibweise, es sei denn, das importierende Modul muss Submodule mit
demselben Namen aus verschiedenen Paketen verwenden.


6.4.2. Verweise innerhalb eines Pakets
--------------------------------------

Wenn Pakete in Unterpakete gegliedert sind (wie im Beispiel beim Paket
"sound"  ), kannst du absolute Importe verwenden, um auf Submodule von
gleichrangigen Paketen zu verweisen. Wenn beispielsweise das Modul
"sound.filters.vocoder" das Modul "echo" aus dem Paket "sound.effects"
verwenden muss, kann es "from sound.effects import echo" verwenden.

Du kannst auch relative Importe schreiben, und zwar mithilfe der
Importanweisung in der Form "from module import name"  . Bei diesen
Importen werden führende Punkte verwendet, um das aktuelle und das
übergeordnete Paket anzugeben, die an dem relativen Import beteiligt
sind. Aus dem Modul "surround" kannst du beispielsweise Folgendes
verwenden:

   from . import echo
   from .. import formats
   from ..filters import equalizer

Beachte, dass relative Importe auf dem Namen des Pakets des aktuellen
Moduls basieren. Da das Hauptmodul kein Paket hat, müssen Module, die
als Hauptmodul einer Python-Anwendung dienen sollen, stets absolute
Importe verwenden.

-[ Fußnoten ]-

[1] Tatsächlich sind Funktionsdefinitionen ebenfalls „Anweisungen“,
    die "ausgeführt" werden; durch die Ausführung einer
    Funktionsdefinition auf Modulebene wird der Funktionsname dem
    globalen Namensraum des Moduls hinzugefügt.
