Estoy tratando de entender, ¿qué es un parche de mono o un parche de mono?
¿Es algo así como métodos / operadores que sobrecargan o delegan?
¿Tiene algo en común con estas cosas?
python
terminology
monkeypatching
Sergei Basharov
fuente
fuente
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.
Respuestas:
No, no es como ninguna de esas cosas. Es simplemente el reemplazo dinámico de atributos en tiempo de ejecución.
Por ejemplo, considere una clase que tiene un método
get_data
. Este método realiza una búsqueda externa (en una base de datos o API web, por ejemplo), y varios otros métodos en la clase lo llaman. Sin embargo, en una prueba unitaria, no desea depender de la fuente de datos externa, por lo que reemplaza dinámicamente elget_data
método con un código auxiliar que devuelve algunos datos fijos.Debido a que las clases de Python son mutables, y los métodos son solo atributos de la clase, puedes hacer esto tanto como quieras y, de hecho, incluso puedes reemplazar clases y funciones en un módulo exactamente de la misma manera.
Pero, como lo señaló un comentarista , tenga cuidado al parchear mono:
Si hay algo más además de las llamadas de lógica de prueba
get_data
, también llamará a su reemplazo parcheado en lugar del original, lo que puede ser bueno o malo. Solo ten cuidado.Si existe alguna variable o atributo que también apunta a la
get_data
función en el momento en que la reemplaza, este alias no cambiará su significado y continuará apuntando al originalget_data
. (¿Por qué? Python simplemente vuelve a unir el nombreget_data
de su clase a algún otro objeto de función; otros enlaces de nombre no se ven afectados en absoluto).fuente
pointing to the original get_data function
? ¿Quiere decir que cuando almacena una función dentro de una variable si alguien cambia esa función, la variable continuará apuntando a la anterior?get_data
, vuelves a vincular el nombreget_data
a una función simulada. Si algún otro nombre en algún otro lugar del programa está vinculado a la función-anteriormente-conocida-como-get_data
, nada cambiará para ese otro nombre.Un ejemplo simple se ve así:
Fuente: página de MonkeyPatch en el wiki de Zope.
fuente
En pocas palabras, el parche de mono está haciendo cambios en un módulo o clase mientras se ejecuta el programa.
Ejemplo de uso
Hay un ejemplo de parches de mono en la documentación de Pandas:
Para desglosar esto, primero importamos nuestro módulo:
A continuación, creamos una definición de método, que existe sin consolidar y libre fuera del alcance de cualquier definición de clase (dado que la distinción es bastante insignificante entre una función y un método independiente, Python 3 elimina el método independiente):
A continuación, simplemente adjuntamos ese método a la clase en la que queremos usarlo:
Y luego podemos usar el método en una instancia de la clase, y eliminar el método cuando hayamos terminado:
Advertencia para el cambio de nombre
Si está usando el cambio de nombre (prefijar los atributos con un doble guión bajo, que altera el nombre y que no recomiendo), tendrá que cambiar el nombre manualmente si hace esto. Como no recomiendo el cambio de nombre, no lo demostraré aquí.
Ejemplo de prueba
¿Cómo podemos usar este conocimiento, por ejemplo, en las pruebas?
Supongamos que necesitamos simular una llamada de recuperación de datos a una fuente de datos externa que resulte en un error, porque queremos asegurar un comportamiento correcto en tal caso. Podemos mono parchear la estructura de datos para garantizar este comportamiento. (Entonces, usando un nombre de método similar al sugerido por Daniel Roseman :)
Y cuando lo probamos para detectar un comportamiento que se basa en que este método genera un error, si se implementa correctamente, obtendremos ese comportamiento en los resultados de la prueba.
Simplemente hacer lo anterior alterará el
Structure
objeto durante la vida útil del proceso, por lo que querrá usar configuraciones y desmontajes en sus pruebas de unidad para evitar hacerlo, por ejemplo:(Si bien lo anterior está bien, probablemente sería una mejor idea usar la
mock
biblioteca para parchear el código.mock
Elpatch
decorador sería menos propenso a errores que hacer lo anterior, lo que requeriría más líneas de código y, por lo tanto, más oportunidades para introducir errores Todavía tengo que revisar el código,mock
pero imagino que usa parches de mono de manera similar).fuente
De acuerdo con Wikipedia :
fuente
Primero: el parcheado de monos es un hack malvado (en mi opinión).
A menudo se usa para reemplazar un método en el nivel de módulo o clase con una implementación personalizada.
El caso de uso más común es agregar una solución alternativa para un error en un módulo o clase cuando no puede reemplazar el código original. En este caso, reemplaza el código "incorrecto" a través de parches de mono con una implementación dentro de su propio módulo / paquete.
fuente
Los parches de mono solo se pueden hacer en lenguajes dinámicos, de los cuales python es un buen ejemplo. Cambiar un método en tiempo de ejecución en lugar de actualizar la definición del objeto es un ejemplo; de manera similar, agregar atributos (ya sean métodos o variables) en tiempo de ejecución se considera parche de mono. A menudo se realizan cuando se trabaja con módulos para los que no tiene la fuente, de modo que las definiciones de objetos no se pueden cambiar fácilmente.
Esto se considera malo porque significa que la definición de un objeto no describe completa o exactamente cómo se comporta realmente.
fuente
Monkey parchear es reabrir las clases o métodos existentes en clase en tiempo de ejecución y cambiar el comportamiento, que debe usarse con precaución, o debe usarlo solo cuando realmente lo necesite.
Como Python es un lenguaje de programación dinámico, las clases son mutables para que pueda volver a abrirlas y modificarlas o incluso reemplazarlas.
fuente
Para obtener más información, consulte [1]: https://medium.com/@nagillavenkatesh1234/monkey-patching-in-python-explained-with-examples-25eed0aea505
fuente