Der Weg, um Namespace-Pakete in Python zu machen

Von Namespace Pakete in verteilen , ich weiß, ich kann von Namespace-Pakete verwenden, um ein großes Python-Paket in mehrere kleinere zu trennen. Es ist wirklich genial. Das Dokument erwähnt auch:

Beachten Sie übrigens, dass der Quellbaum Ihres Projekts die Namespace-Pakete '__init__.py-Dateien (und die __init__.py von allen übergeordneten Paketen) in einem normalen Python-Paketlayout enthalten muss. Diese __init__ .py-Dateien müssen die Zeile enthalten:

  • Unicode (). Decodieren ('utf-8', 'ignore'), der UnicodeEncodeError anhebt
  • Wortfrequenz mit Wörterbuch
  • Wie kann ich die CPU-Auslastung bei der Verwendung des Multiprocessing-Moduls verbessern?
  • So richten Sie einen RQ-Arbeiter auf Heroku mit RedisCloud mit Flasche ein
  • IndexError: Index außerhalb des zulässigen Bereichs: 7
  • PyQt4 verschachtelte Klassen - "RuntimeError: zugrunde liegendes C / C ++ - Objekt wurde gelöscht"
  •  __import__('pkg_resources').declare_namespace(__name__) 

    Dieser Code stellt sicher, dass die Namespace-Paket-Maschine in Betrieb ist und dass das aktuelle Paket als Namespace-Paket registriert ist.

    Ich frage mich, gibt es irgendwelche Vorteile, um die gleiche Hierarchie von Verzeichnissen auf die Hierarchie der Pakete zu halten? Oder das ist nur die technische Anforderung der Namespace-Pakete Feature von distribute / setuptools?

    Ex,

    Ich möchte ein Unterpaket foo.bar zur Verfügung stellen , so dass ich die folgende Hierarchie von Ordnern erstellen und eine __init__.py vorbereiten muss, um setup.py das Namespace-Paket zu erstellen:

     ~foo.bar/ ~foo.bar/setup.py ~foo.bar/foo/__init__.py <= one-lined file dedicated to namespace packages ~foo.bar/foo/bar/__init__.py ~foo.bar/foo/bar/foobar.py 

    Ich bin nicht vertraut mit Namespace-Pakete aber es sieht mir aus, dass 1) foo / bar und 2) (fast) one-lined __init__.py sind Routine-Aufgaben. Sie geben einige Hinweise von "Dies ist ein Namespace-Paket", aber ich denke, wir haben bereits diese Informationen in setup.py ?

    bearbeiten:

    Wie im folgenden Block dargestellt, kann ich ein Namespace-Paket ohne das verschachtelte Verzeichnis und ein-lined __init__.py in meinem Arbeitsverzeichnis haben? Das heißt, können wir bitten setup.py , um diese automatisch zu generieren, indem wir einfach eine Zeile namespace_packages = ['foo'] ?

     ~foo.bar/ ~foo.bar/setup.py ~foo.bar/src/__init__.py <= for bar package ~foo.bar/src/foobar.py 

  • Unterdrückung der wissenschaftlichen Notation in Numpy beim Erstellen von Array aus verschachtelter Liste
  • Iterate python Enum in der Definition Reihenfolge
  • Mehr pythonische Art, diesen Block zu schreiben (und eliminiere: ValueError: Wörterbuch-Update-Sequenz-Element # 0 hat die Länge 1; 2 ist erforderlich)
  • Wie man einen ungültigen json string in python decodiert
  • Replizieren von Zeilen in einem Pandas-Datenrahmen um einen Spaltenwert
  • In Python 2.5 gepickte Daten, in Python 3.1 und dann mit zlib dekomprimieren
  • One Solution collect form web for “Der Weg, um Namespace-Pakete in Python zu machen”

    Ein Namespace-Paket hat vor allem einen besonderen Effekt, wenn es darum geht, ein Sub-Paket zu importieren. Grundsätzlich ist hier, was passiert, beim Import von foo.bar

    • Der Importeur scannt durch sys.path Suche nach etwas, das aussieht wie foo .
    • Wenn es etwas findet, wird es in die entdeckte foo für bar schauen.
    • Wenn bar nicht gefunden wird:
      1. Wenn foo ein normales Paket ist, wird ein ImportError angehoben, was darauf hinweist, dass foo.bar nicht existiert.
      2. Wenn foo ist ein Namespace- Paket, geht der Importeur zurück zu suchen durch sys.path für das nächste Spiel von foo . Der ImportError wird nur dann erhoben, wenn alle Pfade erschöpft sind.

    So das ist, was es tut , aber nicht erklären, warum Sie das mögen könnten. Angenommen, Sie haben eine große, nützliche Bibliothek ( foo ) entworfen, aber als Teil davon haben Sie auch ein kleines, aber sehr nützliches Dienstprogramm ( foo.bar ) entwickelt, das andere python Programmierer nützlich finden, auch wenn sie keinen Gebrauch für die haben Größere Bibliothek

    Du könntest sie zusammen als einen großen Blob eines Pakets verteilen (wie du es entworfen hast), obwohl die meisten Leute, die es benutzen, immer nur das Submodul importieren. Ihre Benutzer würden das schrecklich unbequem finden, weil sie das ganze Ding (alle 200MB davon!) Herunterladen müssen, obwohl sie sich nur wirklich für eine 10-zeilige Utility-Klasse interessieren. Wenn Sie eine offene Lizenz haben, werden Sie wahrscheinlich feststellen, dass mehrere Leute am Ende forking es und jetzt gibt es ein halbes Dutzend divergierende Versionen Ihres Utility-Moduls.

    Du könntest deine ganze Bibliothek umschreiben, damit das Dienstprogramm außerhalb des foo Namensraums lebt (nur bar statt foo.bar ). Sie können das Dienstprogramm separat verteilen, und einige Ihrer Benutzer werden glücklich sein, aber das ist eine Menge Arbeit, vor allem wenn man bedenkt, dass es tatsächlich viele Benutzer mit der ganzen Bibliothek gibt, und so müssen sie ihre umschreiben Programme, um das neue zu benutzen.

    Also, was Sie wirklich wollen, ist ein Weg, um foo.bar auf eigene Faust zu installieren, aber glücklich koexistieren mit foo wenn das auch gewünscht wird.

    Ein Namespace-Paket erlaubt genau das, zwei völlig unabhängige Installationen eines foo Pakets können koexistieren. setuptools wird erkennen, dass die beiden Pakete entworfen sind, um nebeneinander zu leben und höflich die Ordner / Dateien so zu verschieben, dass beide auf dem Pfad sind und als foo erscheinen, eine mit foo.bar und die andere mit dem Rest von foo .

    Du hast zwei verschiedene setup.py Skripte, eine für jeden. foo/__init__.py in beiden Paketen müssen darauf hinweisen, dass sie Namespace-Pakete sind, so dass der Importeur weiß, unabhängig davon, welches Paket zuerst entdeckt wird.

    Python ist die beste Programmiersprache der Welt.