Extending a black box python module
<p>I have a "blackbox" python module which I would like to extend. The module provides a class <code>class Foo</code> with no <code>__init__</code> function, and a helper function <code>FooMaker</code> which returns objects of type <code>Foo</code>. The usual strategy of extending modules:</p>

<pre><code>class ExtendedFoo(blackbox.Foo):
    def __init__(self, x):
        super(ExtendedFoo, self).__init__(x)
</code></pre>

<p>would not work here, since, as mentioned above I need to rely on <code>blackbox.FooMaker</code> instead of <code>Foo</code>'s <code>__init__</code> function.</p>

<p>Any ideas on how to extend the module <code>blackbox</code>?</p>

<p>Unless the module does some serious hacking, you can just replace its members. Note that all references and assignment work on the <code>blackbox.</code> names, not local names!</p>

<p>If you want your new class' <code>__init__</code> to be run inside <code>FooMaker</code>, simply inherit and replace <code>Foo</code>.</p>

<pre><code>import blackbox
class ExtendedFoo(blackbox.Foo):
    def __init__(self, x):
        super(ExtendedFoo, self).__init__(x)

blackbox.Foo = ExtendedFoo
</code></pre>

<p>This way, <code>FooMaker</code> will instantiate classes of <code>ExtendedFoo</code> only.</p>

<p>Alternatively, you can replace <code>FooMaker</code> with your own version.</p>

<pre><code>import blackbox
_bbfoomaker = blackbox.FooMaker  # keep reference so we can use it later
def SuperFooMaker(*fooargs, **fookwargs):
    new_instance = _bbfoomaker(*fooargs, **fookwargs)
    new_instance.whitebox = True  # or whatever

blackbox.FooMaker = SuperFooMaker
</code></pre>

<p>The restriction to the second is that if another module does something like <code>from blackbox import FooMaker</code>, your module <em>must</em> be run/imported before. Otherwise, the other module still sees the original factory, similar to how you still have <code>_bbfoomaker</code>.</p>

python python-2.7 cython