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

glyph at divmod.com glyph at divmod.com
Mon Nov 3 10:23:45 EST 2008


On 02:20 pm, terry at jon.es wrote:
>But I like your __new__ approach better, as it puts the logic for 
>creating
>deferreds, adding callbacks to them, doing other stuff etc., into the 
>class
>itself. It's in __new__ instead of __init__, but that seems perfect to 
>me.

In my humble (but correct) opinion, this is actually a lot worse than 
using __init__ :).  I'd like to discourage you from using it.

Using __new__ like this is violating its implicit metaprogramming 
contract within Python.  __new__ is really supposed to be about 
allocation; it means, give me an uninitialized instance of this thing 
(which I will then initialize using __init__).  It is best used to 
implement things like token interning or free lists for small value 
objects.

Keeping __new__ doing what it's supposed to is important to libraries 
which use introspection.  Serialization libraries, twisted.spread.jelly 
being an obvious example, may need to use __new__ as an API in order to 
create cyclic relationships.  Consider the output of this program:

    class Something(object):
        def __new__(cls, *a, **k):
            self = object.__new__(cls, *a, **k)
            oself = SomethingElse(self)
            return oself

    class SomethingElse(object):
        def __init__(self, sth):
            self.sth = sth

    from twisted.spread.jelly import jelly, unjelly

    print unjelly(jelly(Something())).sth

Using __new__ is functionally equivalent to defining a classmethod, as I 
suggested, but rather than using the "classmethod" decorator it relies 
on implicitly hacking into bits of the Python object model.  Explicit is 
better ... well, you know the rest :).




More information about the Twisted-Python mailing list