Was ist ein pythonischer Weg für Dependency Injection?
Einführung
Für Java, Dependency Injection funktioniert als Reine OOP, d.h. Sie bieten eine Schnittstelle implementiert werden und in deine framework-code akzeptiert eine Instanz einer Klasse, die die definierte Schnittstelle.
Nun für Python, Sie sind in der Lage, das gleiche zu tun, aber ich glaube, die Methode war zu viel Aufwand Recht vor, im Falle von Python. Also wie würde dann implementieren Sie es in der Pythonic way?
Anwendungsfall
Sagen, das ist die framework-code:
class FrameworkClass():
def __init__(self, ...):
...
def do_the_job(self, ...):
# some stuff
# depending on some external function
Der Grundlegende Ansatz
Den meisten naiv (und vielleicht die beste?) Weg ist zu verlangen, um die externe Funktion bereitgestellt werden, die in der FrameworkClass
Konstruktor, und dann aufgerufen werden, aus der do_the_job
Methode.
Framework-Code:
class FrameworkClass():
def __init__(self, func):
self.func = func
def do_the_job(self, ...):
# some stuff
self.func(...)
Client-Code:
def my_func():
# my implementation
framework_instance = FrameworkClass(my_func)
framework_instance.do_the_job(...)
Frage
Die Frage ist kurz. Gibt es eine bessere häufigsten verwendeten Pythonic Weg, dies zu tun? Oder vielleicht irgendwelche Bibliotheken die Unterstützung solcher Funktionalität?
UPDATE: die Konkrete Situation
Vorstellen, ich entwickle eine Mikro-web-framework übernimmt die Authentifizierung mittels Token. Dieser Rahmen muss eine Funktion bereitstellen ID
aus den erhaltenen token und dem Benutzer entsprechend, dass ID
.
Offensichtlich, Rahmen weiß nichts über die Benutzer oder anderen Anwendungen, die spezifische Logik, so dass der client-code muss injizieren der Benutzer get-Funktionalität in das framework, um die Authentifizierung arbeiten.
AttributeError
oder TypeError
ausgelöst wird, sonst), aber ansonsten ist es das gleiche. abs
's ABCMeta
Metaklasse mit @abstractmethod
decorator, und es ist keine manuelle überprüfung. Wollen einfach nur einige Möglichkeiten und Anregungen. Die, die Sie zitiert, ist die sauber, ist aber denke ich mit mehr Aufwand. InformationsquelleAutor der Frage bagrat | 2015-07-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sehen Raymond Hettinger - Super als super! - PyCon 2015 für ein argument über, wie super und Mehrfachvererbung statt DI. Wenn Sie keine Zeit haben, zu beobachten, die gesamte video -, Sprung zu minute 15 (aber ich würde empfehlen, gerade alle von it).
Hier ist ein Beispiel, wie man anwenden, was beschrieben wird in diesem video zu deinem Beispiel:
Framework-Code:
Client-Code:
Dieser arbeiten wird, weil das Python-Instandhaltung wird sichergestellt, dass die getUserFromToken client-Methode aufgerufen wird (wenn super() verwendet wird). Den code ändern, wenn du auf Python 2.x.
Einen zusätzlichen Vorteil hier ist, dass dies eine Ausnahme ausgelöst werden, wenn der Kunde nicht bieten eine Implementierung.
Natürlich, das ist nicht wirklich dependency injection, ist es Mehrfachvererbung und Mixins in Verbindung, aber es ist ein Pythonic Weg, um Ihr problem zu lösen.
InformationsquelleAutor der Antwort Serban Teodorescu
Die Art, wie wir tun, dependency injection in unserem Projekt ist die Verwendung des injizieren lib. Überprüfen Sie heraus die Dokumentation. Ich empfehle sehr, es für die DI. Es irgendwie keinen Sinn macht, mit nur einer Funktion, sondern beginnt viel Sinn, wenn Sie zur Verwaltung verschiedener Daten-Quellen, etc, etc.
Nach deinem Beispiel könnte es so Aussehen:
Ihre benutzerdefinierte Funktion:
Irgendwo in der Anwendung, die Sie möchten, erstellen eine bootstrap-Datei, die Spur hält der alle definierten Abhängigkeiten:
Und klicken Sie dann Sie verbrauchen kann der code auf diese Weise:
Ich befürchte, das ist als pythonic, wie es bekommen kann (das Modul hat einige python süße wie Dekoratoren zu injizieren, die durch den parameter etc - überprüfen Sie die docs), wie python nicht haben ausgefallene Sachen wie Schnittstellen oder Typbestimmung.
So zu Ihre Frage zu beantworten direkt sehr schwierig sein würde. Ich denke, die wahre Frage ist: funktioniert die python haben einige native Unterstützung für DI? Und die Antwort ist leider: Nein.
InformationsquelleAutor der Antwort Piotr Mazurek
Habe ich vor einiger Zeit schrieb dependency injection-microframework mit einem Ehrgeiz, um es Pythonic - Dependency Injector. Das ist, wie der code Aussehen kann, im Falle seiner Verwendung:
Hier ist ein link zu detaillierte Beschreibung der in diesem Beispiel - http://python-dependency-injector.ets-labs.org/examples/services_miniapp.html
Hoffe, es kann ein wenig helfen. Für weitere Informationen besuchen Sie bitte:
InformationsquelleAutor der Antwort Roman Mogylatov
Ich denke, dass DI-und möglicherweise AOP sind nicht allgemein als Pythonic, weil der typische Python-Entwickler Vorlieben, sondern darum, dass Funktionen der Sprache.
Als eine Angelegenheit von der Tat, die Sie umsetzen können ein basic-DI-framework <100 Zeilen, mit Metaklassen und Klassen Dekorator.
Für eine weniger invasive Lösung, diese Konstrukte können verwendet werden, um plug-in benutzerdefinierte Implementierungen in ein generisches framework.
InformationsquelleAutor der Antwort Andrea Ratto