【Python】Monkey Patch10 Feb 2014
What is it?
A simple example looks like this:
from SomeOtherProduct.SomeModule import SomeClass def speak(self): return "ook ook eee eee eee!" SomeClass.speak = speak
In this example, if SomeClass? did not already have a speak() method, it does now If it had a speak() method before, the new code has replaced the old method definition.
The motivation for monkeypatching is typically that the developer needs to modify or extend behavior of a third-party product, or Zope itself, and does not wish to maintain a private copy of the source code.
For example, you may wish to add a tab to the Zope Management Interface screens for a core or third-party product. In Zope 2, there is no other easy way to do this short of forking the product. In Zope3, it is easier to reconfigure the system so we shouldn’t need to do this so often.
Monkeypatching Considered Harmful
There are serious drawbacks to monkeypatching:
- If two modules attempt to monkeypatch the same method, one of them (whichever one runs last) “wins” and the other patch has no effect. (In some cases, if the “winning” monkeypatch takes care to call the original method, the other patch(es) may also work; but you must hope that the patches do not have contradictory intentions.)
- It creates a discrepancy between the original source code on disk and the observed behavior. This can be very confusing when troubleshooting, especially for anyone other than the monkeypatch’s author. Monkeypatching is therefore a kind of antisocial behavior.
- Monkeypatches can be a source of upgrade pain, when the patch makes assumptions about the patched object which are no longer true.
So, just because python allows us to be very dynamic, it’s not always a good idea
Wherefore Art Thou Monkeypatch?
(add something about the history of the term here… there was a post about it maybe on zopezen.org a long time ago, but I can’t find it.)