2017-09-03 2 views
0

ich auf eine Python-Bibliothek arbeite (nicht von mir), die wie folgt aussieht:Wie paketiert man eine Bibliothek, deren Import in Python Nebenwirkungen erzeugt?

. 
├── README.md 
├── setup.py 
└── library 
    ├── __init__.py 
    ├── core.py 
    ├── a.py 
    └── b.py 

Die Datei __init__.py nutzen core.py die sich a.py und b.py verwendet. Die wichtige Sache zu beachten ist, dass import library einige Nebenwirkungen hat, die absichtlich beabsichtigt sind.

Allerdings möchte ich dem Benutzer die Möglichkeit geben, Funktionen von core.py ohne irgendwelche Nebenwirkungen zu verwenden. Leider, wie Sie wissen, wird import library.core oder from library import core__init__.py (wo Nebenwirkungen auftreten) sowieso ausführen.

Wissen Sie, wie ich mein Paket und die setup.py reorganisieren könnte, um dieses Problem zu lösen?


Ich dachte so etwas wie dieses:

. 
├── README.md 
├── setup.py 
├── library_core 
│ ├── __init__.py 
│ ├── core.py 
│ ├── a.py 
│ └── b.py 
└── library 
    └── __init__.py # Import library_core and apply side effects 

I setup.py mit packages = ['library', 'library_core'] aktualisieren würde. Auf diese Weise ändert der Import von library nichts, aber der Benutzer könnte dann library_core ohne irgendwelche Nebenwirkungen importieren. Außerdem würde dies das Duplizieren von Code vermeiden und alles würde im selben Repository bleiben.

Leider funktioniert das nicht, weil ich library_core von library nicht importieren kann, da sie nicht an der gleichen Stelle in der Dateistruktur sind.

+0

* „Leider funktioniert das nicht, weil ich nicht die Möglichkeit haben, library_core aus der Bibliothek zu importieren“ * - sieht so aus, als ob das dein Hauptproblem ist, was passiert, wenn du 'from library_core import core' in' library/__ init __. py' probierst? – Kos

+0

@Kos Eigentlich könnte das funktionieren ... Ich habe es zuerst mit 'von ..library_core import * 'was offensichtlich fehlgeschlagen ist, aber einfach' import library_core' funktioniert, sobald das Paket installiert ist ** mit 'python setup.py install'. Ich denke, das ist der richtige Weg. Also werde ich die Frage auslassen. – Delgan

Antwort

0

Mit zwei Paket scheint der beste Weg zu sein.

Die Verwendung von zwei benachbarten Paketen kann nur funktionieren , wenn die gesamte Bibliothek (mit python setup.py install zum Beispiel) installiert ist. Dies verkompliziert die Entwicklung beträchtlich, beispielsweise für Komponententests: es war dann unmöglich, import library zu tun, da library_core nicht gefunden werden konnte, wenn es nicht installiert war.

Also, die beste Lösung ist einfach ein Unterpaket zu machen, und innerhalb der setup.py wo library_core befindet sich dank der package_dir Option.

Die Dateien Baum würde wie folgt aussehen:

. 
├── README.md 
├── setup.py 
└── library 
    ├── __init__.py 
    └── core 
     ├── __init__.py 
     ├── a.py 
     └── b.py 

Und in setup.py:

setup(
    name = 'library', 
    packages = ['library', 'library.core', 'library_core'], 
    package_dir = {'library_core': 'library/core'}, 
    ... 
) 
0

Ich würde empfehlen, dass Sie aufhören, sich auf Nebenwirkungen zu verlassen, und vom Benutzer verlangen, sie explizit auszulösen, indem Sie eine dokumentierte Funktion aufrufen. Sonst kämpfen Sie einen verlorenen Kampf: der Standard ist, die Nebenwirkungen auszulösen, und Sie müssen sie dann rückgängig machen, wenn der Benutzer sie nicht will.

+0

Dies ist nicht meine Bibliothek, es ist bereits sehr beliebt, so dass ich das aktuelle Verhalten nicht ändern kann. – Delgan

+0

Häufige Ausnahmen von dieser Regel sind Polyfill-Bibliotheken. Vergleichen und kontrastieren Sie 'from __future__ import absolute_import'. Aber ja, es ist unbequem, zum Beispiel wird sich flake8 über "unbenutzte" Importe beschweren – Kos

Verwandte Themen