Ich versuche zu verstehen, was ist Affen-Patching oder ein Affen-Patch?
Ist das so etwas wie das Überladen oder Delegieren von Methoden / Operatoren?
Hat es etwas mit diesen Dingen gemeinsam?
python
terminology
monkeypatching
Sergei Basharov
quelle
quelle
Monkey patching is a technique to add, modify, or suppress the default behavior of a piece of code at runtime without changing its original source code.
Antworten:
Nein, es ist nicht wie eines dieser Dinge. Es ist einfach das dynamische Ersetzen von Attributen zur Laufzeit.
Betrachten Sie beispielsweise eine Klasse mit einer Methode
get_data
. Diese Methode führt eine externe Suche durch (z. B. in einer Datenbank oder einer Web-API), und verschiedene andere Methoden in der Klasse rufen sie auf. In einem Komponententest möchten Sie jedoch nicht von der externen Datenquelle abhängig sein. Daher ersetzen Sie dieget_data
Methode dynamisch durch einen Stub, der einige feste Daten zurückgibt.Da Python-Klassen veränderbar sind und Methoden nur Attribute der Klasse sind, können Sie dies beliebig tun - und sogar Klassen und Funktionen in einem Modul auf genau dieselbe Weise ersetzen.
Aber, wie ein Kommentator betonte, seien Sie beim Monkeypatching vorsichtig:
Wenn außer Ihren Testlogik-Aufrufen noch etwas anderes angezeigt wird
get_data
, wird auch Ihr mit Affen gepatchter Ersatz anstelle des Originals aufgerufen - was gut oder schlecht sein kann. Pass auf dich auf.Wenn eine Variable oder ein Attribut vorhanden ist, die bzw.
get_data
das zum Zeitpunkt des Ersetzens auch auf die Funktion verweist, ändert dieser Alias seine Bedeutung nicht und verweist weiterhin auf das Originalget_data
. (Warum? Python bindet den Namenget_data
in Ihrer Klasse nur an ein anderes Funktionsobjekt. Andere Namensbindungen sind davon überhaupt nicht betroffen.)quelle
pointing to the original get_data function
? Meinen Sie, wenn Sie eine Funktion in einer Variablen speichern, wenn jemand diese Funktion ändert, zeigt die Variable weiterhin auf die alte?get_data
ausführen, binden Sie den Namen erneutget_data
an eine Scheinfunktion . Wenn ein anderer Name an einer anderen Stelle im Programm an die Funktion gebunden ist, die früher als bekannt warget_data
, ändert sich für diesen anderen Namen nichts.Ein einfaches Beispiel sieht so aus:
Quelle: MonkeyPatch- Seite im Zope-Wiki.
quelle
Einfach ausgedrückt, beim Affen-Patching werden Änderungen an einem Modul oder einer Klasse vorgenommen, während das Programm ausgeführt wird.
Anwendungsbeispiel
In der Pandas-Dokumentation finden Sie ein Beispiel für das Patchen von Affen:
Um dies aufzuschlüsseln, importieren wir zuerst unser Modul:
Als nächstes erstellen wir eine Methodendefinition, die ungebunden und frei außerhalb des Bereichs von Klassendefinitionen existiert (da die Unterscheidung zwischen einer Funktion und einer ungebundenen Methode ziemlich bedeutungslos ist, beseitigt Python 3 die ungebundene Methode):
Als nächstes hängen wir diese Methode einfach an die Klasse an, für die wir sie verwenden möchten:
Und dann können wir die Methode für eine Instanz der Klasse verwenden und die Methode löschen, wenn wir fertig sind:
Vorsichtsmaßnahme für die Namensverfälschung
Wenn Sie die Namensverknüpfung verwenden (indem Sie Attributen einen doppelten Unterstrich voranstellen, der den Namen ändert und den ich nicht empfehle), müssen Sie die Namensverknüpfung manuell durchführen, wenn Sie dies tun. Da ich das Mangeln von Namen nicht empfehle, werde ich es hier nicht demonstrieren.
Testbeispiel
Wie können wir dieses Wissen zum Beispiel beim Testen nutzen?
Angenommen, wir müssen einen Datenabrufaufruf an eine externe Datenquelle simulieren, der zu einem Fehler führt, da wir in einem solchen Fall ein korrektes Verhalten sicherstellen möchten. Wir können die Datenstruktur mit Affen patchen, um dieses Verhalten sicherzustellen. (Verwenden Sie also einen ähnlichen Methodennamen wie von Daniel Roseman vorgeschlagen :)
Und wenn wir es auf Verhalten testen, bei dem diese Methode einen Fehler auslöst, erhalten wir dieses Verhalten bei korrekter Implementierung in den Testergebnissen.
Structure
Wenn Sie nur die oben genannten Schritte ausführen, ändert sich das Objekt für die Dauer des Prozesses. Daher sollten Sie in Ihren Unittests Setups und Teardowns verwenden, um dies zu vermeiden, z.(Obwohl das oben Genannte in Ordnung ist, wäre es wahrscheinlich eine bessere Idee, die
mock
Bibliothek zum Patchen des Codes zu verwenden.mock
Derpatch
Dekorateur wäre weniger fehleranfällig als das oben Genannte, was mehr Codezeilen und damit mehr Möglichkeiten zur Einführung von Fehlern erfordern würde Ich habe den Code noch nicht überprüft,mock
aber ich stelle mir vor, dass er Affen-Patches auf ähnliche Weise verwendet.)quelle
Laut Wikipedia :
quelle
Erstens: Das Patchen von Affen ist ein böser Hack (meiner Meinung nach).
Es wird häufig verwendet, um eine Methode auf Modul- oder Klassenebene durch eine benutzerdefinierte Implementierung zu ersetzen.
Der häufigste Anwendungsfall ist das Hinzufügen einer Problemumgehung für einen Fehler in einem Modul oder einer Klasse, wenn Sie den ursprünglichen Code nicht ersetzen können. In diesem Fall ersetzen Sie den "falschen" Code durch Affen-Patching durch eine Implementierung in Ihrem eigenen Modul / Paket.
quelle
Das Patchen von Affen kann nur in dynamischen Sprachen durchgeführt werden, wofür Python ein gutes Beispiel ist. Das Ändern einer Methode zur Laufzeit anstelle des Aktualisierens der Objektdefinition ist ein Beispiel. Ebenso wird das Hinzufügen von Attributen (ob Methoden oder Variablen) zur Laufzeit als Affen-Patching betrachtet. Diese werden häufig ausgeführt, wenn Sie mit Modulen arbeiten, für die Sie nicht die Quelle haben, sodass die Objektdefinitionen nicht einfach geändert werden können.
Dies wird als schlecht angesehen, da die Definition eines Objekts nicht vollständig oder genau beschreibt, wie es sich tatsächlich verhält.
quelle
Beim Affen-Patching werden die vorhandenen Klassen oder Methoden in der Klasse zur Laufzeit erneut geöffnet und das Verhalten geändert. Dies sollte mit Vorsicht angewendet werden, oder Sie sollten es nur verwenden, wenn Sie es wirklich benötigen.
Da Python eine dynamische Programmiersprache ist, können Klassen geändert werden, sodass Sie sie erneut öffnen und ändern oder sogar ersetzen können.
quelle
Weitere Informationen finden Sie unter [1]: https://medium.com/@nagillavenkatesh1234/monkey-patching-in-python-explained-with-examples-25eed0aea505
quelle