[Python-Dev] Monkeypatching idioms -- elegant or ugly?

Guido van Rossum guido at python.org
Tue Jan 15 16:37:50 CET 2008


I ran into the need of monkeypatching a large number of classes (for
what I think are very good reasons :-) and invented two new recipes.
These don't depend on Py3k, and the second one actually works all the
way back to Python 2.2. Neither of these allows monkeypatching
built-in types like list. If you don't know what monkeypatching is,
see see http://en.wikipedia.org/wiki/Monkey_patch.

I think it's useful to share these recipes, if only to to establish
whether they have been discovered before, or to decide whether they
are worthy of a place in the standard library. I didn't find any
relevant hits on the ASPN Python cookbook.

First, a decorator to add a single method to an existing class:

def monkeypatch_method(cls):
    def decorator(func):
        setattr(cls, func.__name__, func)
        return func
    return decorator

To use:

from <somewhere> import <someclass>

@monkeypatch_method(<someclass>)
def <newmethod>(self, args):
    return <whatever>

This adds <newmethod> to <someclass>

Second, a "metaclass" to add a number of methods (or other attributes)
to an existing class, using a convenient class notation:

def monkeypatch_class(name, bases, namespace):
    assert len(bases) == 1, "Exactly one base class required"
    base = bases[0]
    for name, value in namespace.iteritems():
        if name != "__metaclass__":
            setattr(base, name, value)
    return base

To use:

from <somewhere> import <someclass>

class <newclass>(<someclass>):
    __metaclass__ = monkeypatch_class
    def <method1>(...): ...
    def <method2>(...): ...
    ...

This adds <method1>, <method2>, etc. to <someclass>, and makes
<newclass> a local alias for <someclass>.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list