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