Welcome, guest | Sign In | My Account | Store | Cart

Hack a class's __init__ method without subclassing the class because a) you can't modify the original class and b) you can't modify other classes already using the first class. This is a gross hack that should only be used to work around flaws in libraries you have no control over. I've changed the names to protect the innocent.

Python, 36 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
"""HACK: Make module.ClassWithUnsafeInit safe."""

import module


def enable_safety():
    """HACK: Make ClassWithUnsafeInit safe.

    module.ClassWithUnsafeInit does something unsafe.  

    Move the old ClassWithUnsafeInit.__init__ method out of the way--name it
    _NowSafeOrigInit.  Move the old ClassWithUnsafeInit class out of the
    way--name it _NowSafeClassWithUnsafeInit.  Create a new function,
    _NowSafeNewClassWithUnsafeInit, in place of the ClassWithUnsafeInit class
    that instantiates _NowSafeClassWithUnsafeInit and then calls
    _NowSafeClassWithUnsafeInit._NowSafeOrigInit (thanks go to Paul Abrams for
    this second part of the hack).  Last of all, ClassWithUnsafeInit has a
    ClassWithUnsafeInitClass attribute.  Set this to
    _NowSafeNewClassWithUnsafeInit.  I accept the fact that there's probably a
    special place in programmer hell for me (and Paul).

    This must be called exactly once, and it must be called before
    ClassWithUnsafeInit is used for the first time.

    """
    ClassWithUnsafeInit._NowSafeOrigInit = ClassWithUnsafeInit.__init__
    module._NowSafeClassWithUnsafeInit = ClassWithUnsafeInit
    ClassWithUnsafeInit = _NowSafeNewClassWithUnsafeInit
    ClassWithUnsafeInitClass = _NowSafeNewClassWithUnsafeInit


def _NowSafeNewClassWithUnsafeInit(*args, **kargs):
    fs = module._NowSafeClassWithUnsafeInit()
    # Do whatever you need here.
    fs._NowSafeOrigInit(*args, **kargs) 
    return fs

This shows you how to replace an __init__ method. The HasFriends recipe shows you how to add (and thus replace) any other type of method.