__all__ in Python

Hiten Kanwar 30 November 2021
__all__ in Python

Wenn wir tiefer in Pakete und Module einsteigen, werden wir möglicherweise auf die Variable __all__ stoßen, die in verschiedenen _init_.py-Dateien festgelegt ist.

Die __init__.py-Dateien sind die Dateien, die Python veranlassen, die Verzeichnisse als einige Pakete zu behandeln, die Pakete enthalten. Diese Datei verhindert, dass Verzeichnisse mit ähnlichen Namen, wie z. B. Zeichenketten, gültige Module verbergen, die später in einem Modulsuchpfad vorkommen könnten.

__init__.py kann im einfachsten Fall eine leere Datei sein, kann aber auch den Initialisierungscode für das Paket ausführen oder die Variable __all__ setzen.

Daher kann die __init__.py die Variablen __all__ für ein Paket deklarieren.

Eine Liste der öffentlichen Objekte dieses Moduls wird in der Variablen __all__ angegeben. Er wird durch den import * interpretiert. Diese Variable überschreibt die Vorgabe, alles auszublenden, was mit einem Unterstrich aus dem angegebenen Namespace beginnt.

Zum Beispiel,

__all__ = ["a", "b"]
c = 5
a = 10


def b():
    return "b"

Nun importieren wir dies in den folgenden Code.

from sample import *

print(a)  # will work fine
print(b)  # will work fine
print(c)  # will generate an error

Im obigen Beispiel haben wir mit import * alle öffentlichen Objekte aus der Datei sample.py in diese Datei importiert. Dies bedeutet, dass diese Datei alle öffentlichen Objekte der Datei sample.py importiert und unterstützt.

Die Objekte a und b werden importiert und der neue Code funktioniert dort einwandfrei, wo diese Objekte verwendet werden. Das Problem entsteht bei der Verwendung des dritten Objekts c. Dieses Objekt wird nie in die neue Datei importiert, da es kein öffentliches Objekt ist, da es nicht Teil der Variablen __all__ ist. Dieser Teil des Codes generiert also einen Fehler.

Dazu gibt es eine Alternative. Standardmäßig übernimmt Python die Verantwortung, alle Namen zu exportieren, die nicht mit einem Unterstrich _ beginnen. Und auf diesen Mechanismus konnte man sich sicher verlassen. In der Python-Standardbibliothek verlassen sich einige Pakete darauf, aber um dies zu tun, alias sie ihre Importe, zum Beispiel os als _os, sys als _sys usw.

Die Verwendung der Konvention _ ist praktischer, da sie die Redundanz der wiederholten Namensnennung beseitigt. Aber es fügt die Redundanz für Importe hinzu (wenn Sie viele haben), und es ist einfacher, dies konsequent zu vergessen.

Viele Pakete in der Standardbibliothek verwenden __all__. Es ist sinnvoll, die Präfixkonvention _ anstelle von __all__ zu verwenden, wenn Sie sich noch im frühen Entwicklungsmodus befinden und keine Benutzer haben und Ihre API ständig optimieren. Vielleicht gibt es einige Benutzer, aber einer hat Unit-Tests, die die API abdecken und die API immer noch aktiv aktualisieren und ergänzen und in der Entwicklung optimieren.