terça-feira, abril 30, 2013

Monkey patch em Python

Monkey patch, o patch do macaco! Não explica muita coisa, não é? Na comunidade Python é uma expressão bastante comum. Para entender seu significado, vejamos o seguinte exemplo.

Considere que temos uma classe Robot escrita no módulo (arquivo python) chamado agents.py.

código original (agents.py):

class Robot(object):
    def __init__(self):
        self.position = 0

    def ahead(self):
        self.position += 1
 

    def other_method(self):
        print "Other method"


       
O monkey patch consiste em susbstituir atributos, métodos, funções e até classes de outro módulo em tempo de execução. No nosso exemplo, poderíamos fazer um monkey patch do método ahead() da classe Robot da seguinte maneira:

código (patch.py):

import agents

def monkey_ahead(self_like_parameter):

    print "MONKEY PATCH"
    self_like_parameter.position += 3

if __name__ == "__main__":
    agents.Robot.ahead = monkey_ahead
    my_robot = agents.Robot()
    my_robot.ahead()
    print my_robot.position
    my_robot.other_method()


Execute python patch.py e terá o seguinte resultado:

$ python patch.py
MONKEY PATCH
3
Other method


O (monkey) patch foi realizado na linha agents.Robot.ahead = monkey_ahead. Aqui a função monkey_ahead fez se passar pelo método ahead da classe Robot existente no módulo agents.

Isso é possível devido à tipagem dinâmica do Python (também conhecida como "duck typing").

Pelos resultados obtidos, verifica-se também que outros métodos (como other_method) e atributos (como position) continuam acessíveis e funcionando.

Podemos dizer então que o monkey patch é um enxerto no código. É um remendo! E claramente é algo que deve ser evitado ou, no mínimo, usado com extremo cuidado.

Fica bastante claro que o uso de monkey patch é totalmente acoplado ao código original. E isso é ruim. Se for usar, saiba o que está fazendo.


Outras fontes para consulta:

http://www.mindfiresolutions.com/Monkey-Patching-in-Python-1238.php
http://stackoverflow.com/questions/5626193/what-is-monkey-patching

Nenhum comentário: