Kann sich das jemand erklären __all__ in Python?
Habe ich Python mehr und mehr, und ich sehe immer die variable __all__
set in verschiedenen __init__.py
- Dateien. Kann mir jemand erklären, was das bedeutet?
InformationsquelleAutor varikin | 2008-09-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist eine Liste der öffentlichen Objekte, die von diesem Modul, wie interpretiert von
import *
. Es überschreibt die Standard -, alles zu verstecken, die mit einem Unterstrich beginnt.__all__
wenn__all__
vorhanden ist, sind nicht gerade versteckt; Sie können gesehen werden und optimal erreicht in der Regel, wenn Sie Ihre Namen wissen. Es ist nur im Fall von "import *", was nicht empfehlenswert ist jedenfalls, dass die Unterscheidung trägt kein Gewicht.das stimmt nicht ganz entweder: Es wird empfohlen, nur die import-Module, die Sie kennen, entwickelt für
import *
(wie z.B.tk
). Ein guter Hinweis, wenn dies der Fall ist, ist das Vorhandensein von__all__
oder Namen beginnend mit Unterstrich im Modul code.Öffentlichen und internen Schnittstellen - python.org/dev/peps/pep-0008/#id50, Um eine bessere Unterstützung der Selbstbeobachtung, Module sollte ausdrücklich erklären, die Namen in Ihren öffentlich-API mithilfe der __all__ attribute. Einstellung __alle__, um eine leere Liste zeigt an, dass das Modul hat keine öffentliche API.
InformationsquelleAutor Jimmy
Verlinkt, aber nicht explizit hier erwähnt, ist, Wann genau
__all__
verwendet wird. Es ist eine Liste von strings zu definieren, welche Symbole ein Modul exportiert werden, wennfrom <module> import *
auf dem Modul.Beispielsweise den folgenden code in ein
foo.py
explizit exportiert die Symbolebar
undbaz
:Diese Symbole können dann importiert werden, etwa so:
Wenn die
__all__
oben auskommentiert ist, wird dieser code wird dann ausgeführt, um Abschluss, wie das default-Verhaltenimport *
ist, importieren Sie alle Symbole, die nicht mit einem Unterstrich beginnen, aus den gegebenen namespace.Referenz: https://docs.python.org/tutorial/modules.html#importing-from-a-package
HINWEIS:
__all__
wirkt sich auf diefrom <module> import *
Verhalten nur. Mitglieder, die nicht erwähnt in__all__
sind weiterhin von außen zugänglich-Modul und können importiert und mitfrom <module> import <member>
.InformationsquelleAutor Alec Thomas
Bin ich nur hinzufügen, dass diese um genau zu sein:
Alle anderen Antworten beziehen sich auf Module. Die ursprüngliche Frage ausdrücklich erwähnt
__all__
im__init__.py
Dateien, so ist dies über python Pakete.Generell
__all__
kommt nur ins Spiel, wenn diefrom xxx import *
Variante derimport
- Anweisung verwendet wird. Dies gilt für Pakete als auch für Module.Das Verhalten der Module wird erklärt, in dem anderen Antworten. Das genaue Verhalten für Pakete beschrieben ist hier im detail.
Kurz
__all__
auf Paket-Ebene bedeutet ungefähr das gleiche wie für Module, außer es beschäftigt sich mit Module im Paket (im Gegensatz zu der Angabe Namen innerhalb des Moduls). So__all__
gibt an, dass alle Module, die geladen werden sollen und importiert Sie in den aktuellen namespace, wenn Sie uns mitfrom package import *
.Der große Unterschied ist, dass, wenn Sie weglassen die Erklärung der
__all__
in einem Paket ist__init__.py
die Aussagefrom package import *
wird nicht importieren, was bei allen (mit Ausnahmen erklärt in der Dokumentation, siehe link oben).Auf der anderen Seite, wenn Sie weglassen
__all__
in einem Modul, der "Stern " importieren" importiert alle Namen (nicht beginnend mit einem Unterstrich) im Modul definiert.from package import *
noch importieren alles definiert in__init__.py
, auch wenn es keineall
. Der wichtige Unterschied ist, dass ohne__all__
wird es nicht automatisch importieren Sie alle Module definiert im package-Verzeichnis.InformationsquelleAutor MartinStettner
Was bedeutet
__all__
tun?Erklärt er die semantisch mit den "öffentlichen" Namen aus einem Modul. Wenn es einen Namen in
__all__
Benutzer zu erwarten sind, es zu benutzen, und Sie können die Erwartung haben, er wird sich nicht ändern.Es auch programmatische betrifft:
import *
__all__
in einem Modul, z.B.module.py
:bedeutet, dass, wenn Sie
import *
aus dem Modul, nur die Namen in der__all__
importiert werden:Dokumentation tools
Dokumentation und code-Vervollständigung-tools können (eigentlich) auch Einsicht in die
__all__
zu bestimmen, was Namen, um zu zeigen, wie aus einem Modul.__init__.py
macht ein Verzeichnis ein Python-PaketAus der docs:
Also die
__init__.py
erklären können, die__all__
für eine Paket.Verwaltung eine API:
Ein Paket besteht in der Regel aus Modulen, die sich importieren einer anderen, die aber unbedingt zusammen gebunden mit einem
__init__.py
- Datei. Diese Datei ist, was macht das Verzeichnis eine aktuelle Python-Paket. Zum Beispiel, sagen Sie Folgendes:in der
__init__.py
Sie schreiben:und in
module_1
Sie haben:und in
module_2
Sie haben:Und jetzt haben Sie präsentiert eine komplette api, die jemand anderes verwenden können, wenn Sie importieren Sie Ihre Paket, etwa so:
Und nicht alle die anderen Namen, die Sie verwendet, wenn Sie Ihre Module überladen den
package
namespace.__all__
im__init__.py
Nach mehr Arbeit, vielleicht haben Sie beschlossen, dass die Module zu groß und müssen aufgeteilt werden. Also tun Sie das folgende:
Und in jedem
__init__.py
deklarieren Sie eine__all__
, z.B. bei module_1:Und module_2 die
__init__.py
:Und Sie können ganz einfach Dinge in Ihrer API, die Sie verwalten können, auf die subpackage Ebene statt unterpackage Modul-Ebene. Wenn Sie hinzufügen möchten, einen neuen Namen für den API -, Sie aktualisieren einfach die
__init__.py
, z.B. in module_2:Und wenn du nicht bereit bist zu veröffentlichen
Baz
in der top-level-API, die in Ihrer top-level -__init__.py
Sie haben könnte:und wenn Ihr Nutzer sich über die Verfügbarkeit von
Baz
, können Sie es verwenden:aber wenn Sie es nicht wissen, andere tools (wie pydoc) nicht informieren Sie.
Können Sie später ändern, wenn
Baz
ist bereit für die prime time:, Indem
_
versus__all__
:Standardmäßig Python exportieren werden alle Namen, die nicht mit einem
_
. Sie sicherlich könnte beruhen auf diesem Mechanismus. Einige Pakete sind in der Python-standard-Bibliothek, in der Tat, tun auf diese angewiesen sind, aber dies zu tun, Sie alias Ihre Importe, zum Beispiel, inctypes/__init__.py
:Mithilfe der
_
Konvention wäre eleganter, da er entfernt die Redundanz der Benennung der Namen wieder. Aber er fügt hinzu, die Redundanz für die Einfuhr (wenn Sie haben eine Menge von Ihnen) und es ist einfach zu vergessen, dies zu tun konsequent - und das Letzte, was Sie wollen, ist zu haben, um auf unbestimmte Zeit die Unterstützung etwas, das Sie bestimmt nur ein Implementierungsdetail, nur weil man vergessen hat, ein Präfix_
bei der Benennung einer Funktion.Ich persönlich Schreibe ein
__all__
früh in meiner Entwicklung Lebenszyklus für Module, so dass andere Benutzer meinen code wissen, was Sie verwenden sollten, und nicht verwenden.Meisten Pakete in der standard-Bibliothek auch verwenden
__all__
., Wenn die Vermeidung
__all__
Sinn machtMacht es Sinn, zu bleiben, um die
_
prefix-Konvention anstelle von__all__
wenn:Ein
export
decoratorDer Nachteil bei der Verwendung
__all__
ist, dass Sie schreiben die Namen von Funktionen und Klassen werden doppelt exportiert - und die Informationen werden getrennt von den Definitionen. Wir könnte Verwendung eines Dekorator löst dieses problem.Habe ich die Idee für solch eine export-decorator von David Beazley ' s talk auf der Verpackung. Diese Implementierung scheint gut zu funktionieren in CPython traditionellen Importeur. Wenn Sie eine spezielle import-oder Haken-system, weiß ich nicht garantieren, aber wenn Sie es annehmen, ist es ziemlich trivial zu sichern - Sie brauchen nur, um Sie manuell fügen Sie die Namen wieder in die
__all__
So, zum Beispiel, eine utility-Bibliothek, definieren Sie die decorator:
und dann, wo würden Sie definieren eine
__all__
Sie dies tun:Und dies funktioniert sehr gut, ob die Ausführung als Haupt-oder importiert durch eine andere Funktion.
- Und API-Bereitstellung mit
import *
wird auch funktionieren:@export
Dekorateur.Dies hat im Alleingang schon die hilfreichste Antwort, die ich je gesehen habe in Bezug auf zu helfen, ein relativ neues python-Entwickler verstehen, den Prozess der Import der Module/Pakete mit
__init__.py
und die Verwendung von__all__
InformationsquelleAutor Aaron Hall
Es ändert sich auch was pydoc zeigen:
module1.py
module2.py
$ pydoc module1
$ pydoc "Modul2"
Ich erkläre
__all__
in allen meinen Modulen, sowie Unterstrich interne details, die wirklich helfen, bei der Verwendung von Dinge, die Sie noch nie verwendet haben, bevor Sie im live-Dolmetscher-Sitzungen.InformationsquelleAutor L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
Vom (Eine Inoffizielle) Python Referenz Wiki:
InformationsquelleAutor Lasse Vågsæther Karlsen
__all__
passt die Sternchen in<module> importieren *
__all__
passt die Sternchen in<package> importieren *
Einen Modul ist ein
.py
- Datei soll importiert werden.Einen Paket ist ein Verzeichnis mit einem
__init__.py
- Datei. Ein Paket enthält in der Regel Module.MODULE
__all__
lässt Menschen weiß, die "öffentlichen" Funktionen eines Modul.[@AaronHall] Auch, pydoc erkennt Sie.[@Longpoke]von Modul import *
Sehen, wie
swiss
undcheddar
gebracht werden, in den lokalen namespace, aber nichtgouda
:Ohne
__all__
ist, jedem symbol (die nicht mit einem Unterstrich beginnen) wäre möglich gewesen.Importe ohne
*
sind nicht betroffen__all__
import Modul
von Modul import Namen
import Modul als localname
PAKETE
In der
__init__.py
Datei von einem Paket__all__
ist eine Liste von strings mit den Namen der öffentlich-Module oder andere Objekte. Diese features sind verfügbar, um wildcard-imports. Wie bei Modulen__all__
passt die*
beim wildcard-Import aus dem Paket.[@MartinStettner]Hier ein Auszug aus der MySQL Connector Python
__init__.py
:Standardmäßig der Fall, Sternchen ohne
__all__
für ein Paket, ist kompliziert, weil die offensichtliche Verhalten würde teuer werden: verwenden Sie die Datei-system für alle Module im Paket. Stattdessen in meine Lektüre der Dokumente, werden nur die Objekte definiert, die in__init__.py
importiert werden:[PEP 8, @ToolmakerSteve]
from <package> import *
ohne__all__
im__init__.py
ist nicht importieren aller Module.Danke @Jatimir, ich habe klargestellt, so gut ich konnte laufen, ohne Experimente. Wollte mir fast zu sagen, dass dieser Fall (Stern ohne alle für ein Paket) verhält sich als wenn
__init__.py
wurden ein Modul. Aber ich bin mir nicht sicher, dass das richtig ist, oder insbesondere, wenn der Unterstrich vorangestellt Objekte sind ausgeschlossen. Auch habe ich mehr klar getrennt sind die Abschnitte über die MODULE und PAKETE. Ihre Gedanken?InformationsquelleAutor Bob Stein
Kurze Antwort
__all__
betrifftfrom <module> import *
Aussagen.Lange Antwort
Betrachten Sie dieses Beispiel:
In
foo/__init__.py
:(Implizit), Wenn wir nicht definieren
__all__
, dannfrom foo import *
wird nur der import von Namen definiert, die infoo/__init__.py
.(Explicit) Wenn wir definieren
__all__ = []
, dannfrom foo import *
importieren nichts.(Explicit) Wenn wir definieren
__all__ = [ <name1>, ... ]
, dannfrom foo import *
wird nur der import mit diesen Namen.Beachten Sie, dass in der impliziten Fall, python nicht importieren Sie Namen beginnend mit
_
. Jedoch, Sie können erzwingen, dass der Import solcher Namen mit__all__
.Können Sie die Python-Dokument hier.
InformationsquelleAutor Cyker
__all__
wird verwendet, um document die öffentliche API Python-Modul. Obwohl es optional ist, ist__all__
verwendet werden soll.Hier ist der entsprechende Auszug aus the Python language reference:
PEP 8 verwendet ähnliche Formulierungen, obwohl es auch deutlich macht, dass die eingeführten Namen sind nicht Teil der öffentlichen API, wenn
__all__
fehlt:Außerdem, wie schon in anderen Antworten
__all__
wird benutzt, um die Platzhalter für Pakete importieren:InformationsquelleAutor Mihai Capotă
Zusätzlich zu den vorhandenen Antworten
__all__
muss nicht eine Liste. Gemäß der Dokumentation auf derimport
- Anweisung, wenn Sie definiert ist,__all__
muss ein Sequenz von Zeichenfolgen, die Namen definiert oder importiert das Modul. So können Sie auch mit einem Tupel zu speichern einige Speicher-und CPU-Zyklen. Vergessen Sie nicht, ein Komma, wenn das Modul definiert eine einzelne öffentliche name:__all__ = ('some_name',)
InformationsquelleAutor Eugene Yarmash