J'essaie de comprendre, qu'est-ce qu'un patch de singe ou un patch de singe?
Est-ce quelque chose comme des méthodes / opérateurs surchargeant ou déléguant?
At-il quelque chose de commun avec ces choses?
python
terminology
monkeypatching
Sergei Basharov
la source
la source
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.
Réponses:
Non, ce n'est comme aucune de ces choses. Il s'agit simplement du remplacement dynamique d'attributs lors de l'exécution.
Par exemple, considérons une classe qui a une méthode
get_data
. Cette méthode effectue une recherche externe (sur une base de données ou une API Web, par exemple), et diverses autres méthodes de la classe l'appellent. Cependant, dans un test unitaire, vous ne voulez pas dépendre de la source de données externe - vous remplacez donc dynamiquement laget_data
méthode par un stub qui renvoie des données fixes.Parce que les classes Python sont mutables et que les méthodes ne sont que des attributs de la classe, vous pouvez le faire autant que vous le souhaitez - et, en fait, vous pouvez même remplacer les classes et les fonctions d'un module exactement de la même manière.
Mais, comme l'a fait remarquer un intervenant, soyez prudent lorsque vous effectuez une opération de monkeyping:
Si quelque chose d'autre que vos appels de logique de test appelle
get_data
également, il appellera également votre remplacement patché par un singe plutôt que l'original - ce qui peut être bon ou mauvais. Méfiez-vous.S'il existe une variable ou un attribut qui pointe également vers la
get_data
fonction au moment où vous le remplacez, cet alias ne changera pas sa signification et continuera à pointer vers l'originalget_data
. (Pourquoi? Python lie simplement le nomget_data
de votre classe à un autre objet fonction; les autres liaisons de nom ne sont pas du tout affectées.)la source
pointing to the original get_data function
? Voulez-vous dire que lorsque vous stockez une fonction dans une variable, si quelqu'un change cette fonction, la variable continuera à pointer vers l'ancienne?get_data
, vous liez à nouveau le nomget_data
à une fonction factice . Si un autre nom quelque part ailleurs dans le programme est lié à la fonction-anciennement connue sous le nom deget_data
, rien ne changera pour cet autre nom.Un exemple simple ressemble à ceci:
Source: page MonkeyPatch sur le wiki de Zope.
la source
Autrement dit, le patch de singe apporte des modifications à un module ou à une classe pendant que le programme est en cours d'exécution.
Exemple d'utilisation
Il y a un exemple de patch de singe dans la documentation Pandas:
Pour décomposer cela, nous importons d'abord notre module:
Ensuite, nous créons une définition de méthode, qui existe non liée et libre en dehors de la portée de toutes les définitions de classe (puisque la distinction est assez dénuée de sens entre une fonction et une méthode non liée, Python 3 supprime la méthode non liée):
Ensuite, nous attachons simplement cette méthode à la classe sur laquelle nous voulons l'utiliser:
Et puis nous pouvons utiliser la méthode sur une instance de la classe et supprimer la méthode lorsque nous avons terminé:
Avertissement pour la manipulation de nom
Si vous utilisez la manipulation de noms (préfixer les attributs avec un double soulignement, ce qui modifie le nom et que je ne recommande pas), vous devrez manuellement modifier les noms si vous faites cela. Comme je ne recommande pas la manipulation de noms, je ne le démontrerai pas ici.
Exemple de test
Comment pouvons-nous utiliser ces connaissances, par exemple, dans les tests?
Supposons que nous devons simuler un appel de récupération de données vers une source de données externe qui entraîne une erreur, car nous voulons garantir un comportement correct dans un tel cas. Nous pouvons corriger la structure des données par singe pour garantir ce comportement. (Donc, en utilisant un nom de méthode similaire à celui suggéré par Daniel Roseman :)
Et lorsque nous le testons pour un comportement qui repose sur cette méthode générant une erreur, s'il est correctement implémenté, nous obtiendrons ce comportement dans les résultats du test.
Faire simplement ce qui précède modifiera l'
Structure
objet pendant toute la durée du processus, vous voudrez donc utiliser des configurations et des démontages dans vos tests pour éviter de le faire, par exemple:(Bien que ce qui précède soit correct, ce serait probablement une meilleure idée d'utiliser la
mock
bibliothèque pour patcher le code.mock
Lepatch
décorateur de . Je n'ai pas encore revu le codemock
mais j'imagine qu'il utilise le patch de singe de la même manière.)la source
Selon Wikipedia :
la source
Premièrement: le patching de singe est un hack diabolique (à mon avis).
Il est souvent utilisé pour remplacer une méthode au niveau du module ou de la classe par une implémentation personnalisée.
Le cas d'utilisation le plus courant consiste à ajouter une solution de contournement pour un bogue dans un module ou une classe lorsque vous ne pouvez pas remplacer le code d'origine. Dans ce cas, vous remplacez le "mauvais" code par le patch de singe par une implémentation à l'intérieur de votre propre module / package.
la source
La correction de singe ne peut être effectuée que dans des langages dynamiques, dont python est un bon exemple. La modification d'une méthode au moment de l'exécution au lieu de mettre à jour la définition d'objet en est un exemple; de même, l'ajout d'attributs (qu'il s'agisse de méthodes ou de variables) au moment de l'exécution est considéré comme une correction de singe. Cela se fait souvent lorsque vous travaillez avec des modules dont vous n'avez pas la source, de sorte que les définitions d'objet ne peuvent pas être facilement modifiées.
Ceci est considéré comme mauvais car cela signifie que la définition d'un objet ne décrit pas complètement ou précisément comment il se comporte réellement.
la source
Le patch de singe rouvre les classes ou méthodes existantes dans la classe au moment de l'exécution et modifie le comportement, qui doit être utilisé avec prudence, ou vous ne devez l'utiliser que lorsque vous en avez vraiment besoin.
Comme Python est un langage de programmation dynamique, les classes sont modifiables afin que vous puissiez les rouvrir et les modifier ou même les remplacer.
la source
Pour plus d'informations, veuillez consulter [1]: https://medium.com/@nagillavenkatesh1234/monkey-patching-in-python-explained-with-examples-25eed0aea505
la source