2015-08-21 6 views
5

Nehmen wir an, Sie haben ein großes (Python) Software-Projekt namens Ninja. Es gibt mehrere Teile des Projekts, wie einen Server und einen Client, aber auch eine gemeinsame Infrastrukturbibliothek, die gemeinsame Klassen und Tools enthält. Natürlich würde ich eine Paketstruktur wie folgt erstellen: ninja.core, ninja.server und ninja.client, wo sowohl der Server und der Client Import ninja.core in gewisser Weise. Für Entwicklungszwecke (wir Eclipse mit Subversion) der Kern, Server und Client in verschiedenen Projekten gehalten werden, so dass in einer Ordnerstruktur wie folgt resultierende:Wie können Python-Bibliotheken verschiedener Projekte im selben Paket sein?

eclipse_workspace 
| 
>-Ninja_core 
| | 
| >-ninja 
| | 
| >-core 
| 
>-Ninja_client 
| | 
| >-ninja 
| | 
| >-client 
. 
. 
. 

ein Java-Hintergrund Nachdem ich davon ausgegangen, das wäre möglich, aber es stellte sich heraus (lesen: Importfehler), dass dies nicht funktioniert. Wie in this answer wies darauf hin, es im Allgemeinen nicht möglich ist, beides zu haben ninja.core und ninja.clientes sei denn sie Subpackages des gleichen Pakets ist ninja, was sie nicht sind. Daraus ergibt sich:

Ein Ansatz:

  • Setzen Sie den gesamten Code in einer einzigen eclipse/SVN-Projekt und haben nur ein Paket ninja mit den nach Subpackages.

In einer Produktionsumgebung wollen wir Kern und Server aber nicht Client oder Kern und Client aber nicht Server installieren können. Ich könnte mich irren, aber soweit ich Python-Pakete verstehe, wäre dies mit Ansatz A nicht möglich. Wenn die Projekte getrennt aber kompatibel gehalten werden, scheint es sinnvoll Pakete mit den Namen ninja_core, ninja_client und zu verwenden, was in Tatsache, die Importprobleme zu lösen und alles läuft reibungslos im Entwicklungs-Setup. Um die Anforderung zu können, erfüllenServer und Client installieren unabhängig, kam ich auf die Idee von:

Ansatz B:

  • Erstellen Sie ein neues Projekt mit dem Namen ninja die enthält das Paket ninja
  • Lassen Sie die __init__.py von ninja importieren Sie die anderen Bibliotheken (falls installiert) in einer Weise, dass sie innerhalbzu sein scheinen.

Ich habe das bisher nicht funktioniert und ich denke, dass es nicht einmal möglich sein könnte.Ich dachte an etwas in der Art:

# __init__.py of ninja 
import ninja_core as core 
# or this: 
from ninja_core import core 
# or this: 
import ninja_core.core 

Ich habe diese versucht und habe wieder Importfehler bekommen. Nach dem googeln nach Möglichkeiten, Python-Pakete zu kombinieren und nichts zu meinem Problem zu finden, kam ich hierher.

Ich dachte, dass die ganze Sache vielleicht ein Konstruktionsfehler ist. Sollten Client und Server sogar im selben Paket sein, wenn sie unabhängig voneinander installiert werden können? Ist es eine schlechte Idee, den Client und Server unabhängig installieren zu können? Warum kann ich Pakete in Java erweitern, aber nicht in Python? Was ist die Idee dahinter?

tl; dr

Ich bin die Ninja Bibliothek zu entwickeln, wo ein Benutzer sollte import ninja.client und import ninja.server tun können. Es muss möglich sein, die Bibliotheken für Client und Server separat zu installieren. Wie erreicht man das?

Antwort

3

Vorausgesetzt, dass Sie den Namespace der obersten Ebene ninja leer lassen, wird dies bereits nativ in Python 3.3 und höher unterstützt, siehe PEP 420; alles, was Sie tun müssen, ist das ninja Verzeichnis erstellen und auslassen die __init__.py Datei in diesem Verzeichnis:

eclipse_workspace 
| 
>-Ninja_core 
| | 
| >-ninja 
| | 
| >-core 
|  | 
|  >-__init__.py 
| 
>-Ninja_client 
| | 
| >-ninja 
| | 
| >-client 
|  | 
|  >-__init__.py 

Die ninja Verzeichnisse leer bleiben abgesehen von dem Kind core und client Verzeichnisse. Diese Verzeichnisse tun haben __init__.py Dateien.

In früheren Python-Versionen können Sie die Unterstützung für Namespaces mithilfe von setuptools namespace packages hinzufügen. Die Zope und Plone Projekte haben seit Jahren namespaced Pakete mit setuptools freigegeben.

Das Grundprinzip ist, dass Sie sicherstellen, dass Ihre Projekte Pakete mit setup.py Datei sind, und entweder in development mode oder als Endprodukte installiert sind. Ihre ninja Verzeichnisse tun dann eine __init__.py Datei, aber diese muss enthalten die folgende Zeile nur:

__import__('pkg_resources').declare_namespace(__name__) 

und die setup.py-Datei für jedes Projekt muss den Namensraum deklarieren:

setup(
    # ... 
    namespace_packages = ['ninja'] 
) 
+0

Es funktioniert , aber da der Ordner 'ninja' kein' _init___py' enthält, erkennt eclipse keinen der Unterordner als Pakete. Gibt es dafür eine Option oder eine einfache Lösung? – nfs

+0

Tut mir leid, keine Ahnung; Ich benutze Eclipse oder PyDev nicht selbst; Eine schnelle Google-Anzeige zeigt, dass andere sich darüber beschwert haben, aber ich sehe keine einfachen Fixes für Sie. –

Verwandte Themen