in

python – ¿Qué es el parche de mono?

apple touch icon@2

En pocas palabras, el parche de mono consiste en realizar cambios en un módulo o clase mientras el programa se está ejecutando.

Hay un ejemplo de parcheo de mono en la documentación de Pandas:

import pandas as pd
def just_foo_cols(self):
    """Get a list of column names containing the string 'foo'

    """
    return [x for x in self.columns if 'foo' in x]

pd.DataFrame.just_foo_cols = just_foo_cols # monkey-patch the DataFrame class
df = pd.DataFrame([list(range(4))], columns=["A","foo","foozball","bar"])
df.just_foo_cols()
del pd.DataFrame.just_foo_cols # you can also remove the new method

Para desglosar esto, primero importamos nuestro módulo:

import pandas as pd

A continuación, creamos una definición de método, que existe independiente y libre fuera del alcance de cualquier definición de clase (dado que la distinción no tiene sentido entre una función y un método independiente, Python 3 elimina el método independiente):

def just_foo_cols(self):
    """Get a list of column names containing the string 'foo'

    """
    return [x for x in self.columns if 'foo' in x]

A continuación, simplemente adjuntamos ese método a la clase en la que queremos usarlo:

pd.DataFrame.just_foo_cols = just_foo_cols # monkey-patch the DataFrame class

Y luego podemos usar el método en una instancia de la clase y eliminar el método cuando hayamos terminado:

df = pd.DataFrame([list(range(4))], columns=["A","foo","foozball","bar"])
df.just_foo_cols()
del pd.DataFrame.just_foo_cols # you can also remove the new method

Advertencia sobre la alteración de nombres

Si está utilizando la alteración de nombres (prefijar atributos con un guión bajo doble, que altera el nombre y que no recomiendo), tendrá que alterar el nombre manualmente si hace esto. Como no recomiendo la alteración de nombres, no lo demostraré aquí.

¿Cómo podemos utilizar este conocimiento, por ejemplo, en pruebas?

Digamos que necesitamos simular una llamada de recuperación de datos a una fuente de datos externa que da como resultado un error, porque queremos asegurar un comportamiento correcto en tal caso. Podemos parchear la estructura de datos para asegurar este comportamiento. (Entonces, usando un nombre de método similar al sugerido por Daniel Roseman 🙂

import datasource

def get_data(self):
    '''monkey patch datasource.Structure with this to simulate error'''
    raise datasource.DataRetrievalError

datasource.Structure.get_data = get_data

Y cuando lo probamos para detectar un comportamiento que se basa en este método y genera un error, si se implementa correctamente, obtendremos ese comportamiento en los resultados de la prueba.

El solo hecho de hacer lo anterior alterará el Structure objeto durante la vida del proceso, por lo que querrá usar configuraciones y desmontajes en sus pruebas unitarias para evitar hacer eso, por ejemplo:

def setUp(self):
    # retain a pointer to the actual real method:
    self.real_get_data = datasource.Structure.get_data
    # monkey patch it:
    datasource.Structure.get_data = get_data

def tearDown(self):
    # give the real method back to the Structure object:
    datasource.Structure.get_data = self.real_get_data

(Si bien lo anterior está bien, probablemente sería una mejor idea usar el mock biblioteca para parchear el código. mock‘s patch El 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 en mock pero imagino que usa parches de monos de manera similar).

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Método Python String decode ()

gfg 200x200 min

Python | Obtener la clave del valor en el diccionario