[Twisted-Python] A Python metaclass for Twisted allowing __init__ to return a Deferred

Jean-Paul Calderone exarkun at divmod.com
Sun Nov 2 18:54:44 EST 2008


On Mon, 3 Nov 2008 00:48:20 +0100, Terry Jones <terry at jon.es> wrote:
>I just posted a blog article with title as above: http://bit.ly/1whZUK
>
>Very briefly, I wrote a metaclass to allow you to write classes whose
>__init__ method uses deferreds. Your __init__ can create deferreds, call
>functions that return deferreds, and of course return a deferred itself
>(that's the whole point). Your class instance wont be available until after
>the deferred your __init__ returns has fired.
>
>You use it like this:
>
>    from txDeferredInitMeta import TxDeferredInitMeta
>
>    class MyClass(object):
>        __metaclass__ = TxDeferredInitMeta
>        def __init__(self):
>            d = aFuncReturningADeferred()
>            return d
>
>    def cb((instance, result)):
>        # instance is an instance of MyClass
>        # result is from the callback chain of aFuncReturningADeferred
>        pass
>
>    d = MyClass()
>    d.__instantiate__()
>    d.addCallback(cb)
>
>Metaclass code & test suite at http://foss.fluidinfo.com/txDeferredInitMeta.zip
>
>For more details on how it works see http://bit.ly/1whZUK
>
>I'll be happy to explain why this is useful if anyone cares. Or maybe
>there's a better way to do this that I don't know about. I always have the
>feeling that I know just the barest amount about what's out there in the
>Twisted codebase, and that every problem I run into must have already been
>encountered by many and solved in some insanely elegant and general way.
>In any case, I had fun.

I usually solve this kind of problem like this:

    d = aFuncReturningADeferred()
    d.addCallback(MyClass)
    d.addCallback(cb)

I'll not try to claim anything about the level of elegance, though. :)

For less surprisiness, I'd suggest that you at least restrict the result
of the Deferred returned from __init__ to firing with None or self and
make the argument to the first callback on the Deferred returned by
MyClass() just be the new instance.

Jean-Paul




More information about the Twisted-Python mailing list