On 02:20 pm, terry@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 :).