2012-09-20 7 views
5

Ich verwende __init__.py, um Prüfungen durchzuführen, wenn ich from myprojects.something import blabla mache.Verwendung von __init__.py

Heute begann ich mit pyzmq und ich wollte sehen, was hinter den Kulissen vor sich geht. Also habe ich den Code in GitHub durchsucht und finde (für mich) eine seltsame Verwendung von __init__.py dort, die ich mir nicht erklären kann.

Zum Beispiel zmq/core/__init__.py. Was ist der Sinn der zmq.core.__all__zmq.core.constants, zmq.core.error, zmq.core.message, etc.?

In zmq/__init__.py sehe ich am Ende

__all__ = ['get_includes'] + core.__all__ 

wo get_includes eine Funktion ist, die im Grunde eine Liste mit dem Verzeichnis des Moduls zurückgibt und Verzeichnis UTILS in das übergeordnete Verzeichnis.

Was ist der Sinn davon? Was hat __init.py__ dadurch erreicht?

Antwort

11

Die __all__ ist für wenn jemand from module import * wie dokumentiert here.

Die einzige Lösung ist, dass der Paketautor einen expliziten Index des Pakets bereitstellt. Die Importanweisung verwendet die folgende -Konvention: Wenn der Code __init__.py eines Pakets eine Liste mit dem Namen __all__ definiert, wird dies als Liste der Modulnamen betrachtet, die importiert werden sollen, wenn der Paketimport * auftritt. Es liegt an dem Paketautor , diese Liste auf dem neuesten Stand zu halten, wenn eine neue Version des -Pakets veröffentlicht wird. Paketautoren können sich auch entschließen, nicht zu unterstützen, wenn sie keine Verwendung zum Importieren von * aus ihrem Paket sehen. Für Beispiel könnte die Datei sounds/effects/__init__.py enthalten den folgenden Code:

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

Dies würde bedeuten, dass from sound.effects import * die drei genannten Submodule des Sound-Paket importieren würde.

Eine Verwendung für __all__ ist ein Werkzeug für die Paket-Builder, damit sie ihr Paket in einer Weise zu strukturieren, die für sie arbeitet, während es für die Benutzer bequemer zu machen. Insbesondere im Fall von pyzmq, es kann Sie Code schreiben, wie zum Beispiel:

import zmq 
print zmq.zmq_version() 

Anstatt die vollen gepunkteten Modulnamen zu verwenden:

print zmq.core.version.zmq_version() 

Das Paket Designer von pyzmq __all__ verwenden zu fördern Namespace-Elemente von verschachtelten Modulen bis zur obersten Ebene ihres Namespace, so dass der Benutzer nicht von der Struktur seines Pakets gestört wird.

+0

Ich habe diesen Teil der Dokumentation gelesen, bevor Sie hier nachfragen. Aber das beantwortet meine Frage immer noch nicht. Vielleicht sollte ich anders fragen: Ich dachte, dass der Grund für die Verwendung von 'aus bla import ble' darin bestünde, dass du deinen Namespace kontrollierst, dh du entscheidest, welche Symbole du deinem Namen hinzufügst. – Pablo

+0

Wie im Gegensatz zu C, wo die Verwendung von '# include' eine Kollision mit bereits definierten Funktionen, Variablen usw. verursachen könnte, sollten Sie nur die Symbole importieren, die Sie wirklich benötigen. Ich habe irgendwo in der Python-Dokumentation gelesen, dass die Verwendung von 'from bla import *' keine gute Angewohnheit war. Wenn ja, warum sollten Sie überhaupt '__ all__' definieren? Und wie wird '__all__ = [' get_includes '] + core .__ all__' bei einem 'import *' ausgewertet? – Pablo

+1

von bla import * ist keine gute Gewohnheit, aber es gibt einige Module, für die das im Allgemeinen sicher ist. Ich mache routinemäßig aus Mathe-Import *. Die Dokumentation dieser Module weist oft darauf hin, dass sie so konzipiert sind, dass sie so verwendet werden können und dass sie Feinheiten wie __all__ unterstützen, um es ein wenig einfacher zu machen. Aber von ximport * ist immer noch etwas zu verwenden mit Vorsicht und nur mit Paketen, wo Sie wissen, dass es kein Problem verursacht. – TimothyAWiseman

Verwandte Themen