hat kein brauchbares Konzept der schnittstellenbasierten Programmierung (wie bei C#-Schnittstellen)
Nur weil der Compiler nicht überprüfen kann, ob Sie die Schnittstelle korrekt verwenden, heißt das nicht, dass es "kein brauchbares Konzept für Schnittstellen" gibt. Man dokumentiert eine Schnittstelle und schreibt Unit-Tests.
Was die Globals betrifft, so ist es nicht wie public static
Methoden und Felder von C#- oder Java-Klassen wirklich unterschiedlich sind. Betrachten Sie zum Beispiel, wie java.lang.Math funktioniert. Betrachten Sie nun die Tatsache, dass java.lang.Math ist nicht ein Singleton. Das haben sie aus gutem Grund getan.
Mit all diesen Vorzügen ist es wirklich sinnvoll, einen Container für die Injektion von Abhängigkeiten zu verwenden.
Ich bezweifle es, aber ich habe auch nie wirklich den Sinn von ihnen in C# oder Java gesehen. Dependency Injection ist eine Programmierung Technik meiner Meinung nach. Und es ist auch nicht wirklich viel dabei.
Ich habe immer vermutet, dass Dependency Injection als Entwurfsmuster ein übler Geruch war, der von allem, was eine Klasse "Nazi-Denken" sein muss, erzeugt wurde.
Nein, ist es nicht. Dependency Injection ist in den meisten Fällen eine gute Idee. Sie brauchen auch keine Klasse, in die Sie Abhängigkeiten injizieren. Jedes Mal, wenn Sie einer freien Funktion etwas als Parameter übergeben, anstatt die Funktion eine andere Funktion aufrufen zu lassen, um die Informationen zu erhalten, tun Sie im Grunde das Gleiche: Umkehrung der Kontrolle. In Python können Sie Module in vielerlei Hinsicht ähnlich wie Klassen behandeln (auf jeden Fall mehr als in Java und C#). Es gibt Probleme, die gelöst werden können, indem man Module als Parameter an Funktionen übergibt :)
Bisher denke ich, dass ich Fabriken, Singletons, Multi-Instanz-Objekte, nur durch die Verwendung von Globals abdecken kann.
Singletons sind der schlechte Geruch, wenn überhaupt. In fast jedem Fall, in meiner umfangreichen Erfahrung, existieren sie, weil jemand dachte, es wäre prinzipiell schlecht(TM), ein Global zu haben, ohne wirklich über die möglichen Optionen nachzudenken, oder warum sie diese Art von Zugriff auf ein einzelnes gemeinsames Objekt wollten, oder sogar, warum Globals überhaupt "prinzipiell schlecht(TM)" sind.
Sie könnte eine globale Funktion in Python erstellen, die als Fabrik fungiert. Ich würde jedoch sagen, dass es pythonischer ist, eines der folgenden Dinge zu tun:
a) erstens, wirklich, wirklich machen, wirklich sicher, dass Sie nicht einfach tun können, was Sie wollen, mit __init__
. Ich meine, in einer dynamisch typisierten Sprache kann man auf diese Weise eine ganze Menge erreichen.
b) Wenn __init__
nicht ausreicht, versuchen Sie es mit __new__
um das Verhalten zu kontrollieren.
In Python sind die Klassen selbst Objekte, die aufrufbar sind. Standardmäßig wird durch den Aufruf die Klasse instanziiert. Mit __new__
können Sie sich da einklinken.
c) Verwenden Sie einen Dekorator, der auf die Klasse angewendet wird. Hier ist ein Beispiel, das ein Singleton macht (nur so):
def _singleton(cls):
instance = cls()
result = lambda: instance
result.__doc__ = cls.__doc__
return result
@_singleton
class example(object): pass
Das funktioniert so: Wenn Sie die Klasse dekorieren, _singleton()
aufgerufen wird, wobei die Klasse übergeben wird. Eine Instanz wird erstellt und zwischengespeichert, und _singleton()
gibt eine anonyme Funktion zurück, die beim Aufruf die Instanz zurückgibt. Um die Scharade zu vollenden, wird die Dokumentation der Klasse an die anonyme Funktion angehängt. Dann bindet Python den Namen der Klasse im globalen Bereich wieder an die zurückgegebene anonyme Funktion. Wenn Sie die Funktion also aufrufen, erhalten Sie jedes Mal dieselbe Instanz der Klasse.
Dies kann natürlich immer noch umgangen werden (Sie können z. B. Folgendes tun example().__class__()
um eine andere Instanz zu erhalten), aber es ist viel deutlicher, dass Sie etwas falsch machen, als wenn Sie einfach eine Fabrikfunktion ignorieren, um den Konstruktor normal zu verwenden. Außerdem bedeutet dies, dass der aufrufende Code sich tatsächlich so verhält, als ob er den Konstruktor normal aufrufen würde :)
Die Duck Typing ist die Sache, die mich im Moment, so verwendet, um Schnittstellen zu definieren, dann basierend Klassen auf diesen Schnittstellen und lassen Sie die statische Sachen decken meine Dummheit, dass ich das Gefühl, dass ohne statische Typisierung, Container sind ein bisschen nutzlos.
Sie müssen umdenken: Hören Sie auf, sich darüber Gedanken zu machen, was die Sache, die Ihnen zugesprochen wurde es und sorgen sich um ob es das tun kann, was Sie wollen . So funktioniert das Tippen von Enten.