Glyph's answer matches my experience. To add another reason though, remember back to when I was new to Python, I too wanted to figure out how to asynchronously instantiate an object, I think it's a common desire among new programmers. If the correct answer to that question requires a deep understanding of __init__, __new__, and god only knows what else ( ;-) ), the whole framework becomes more unapproachable. Making the correct answer "a factor function + boring __init__" requires far less deep understanding of Python, and pushes new folks towards good design in general.
Cheers, Alex On Sat, May 16, 2015 at 4:42 PM, Glyph <[email protected]> wrote: > On May 16, 2015, at 8:39 AM, Ben Darnell <[email protected]> wrote: > > > Personally I'd rather use an explicit factory function than __new__ magic > here, but it's possible to experiment with this style. > > > I can tell you from experiments in the Twisted community that this kind of > "async object creation" without an explicit factory function is basically > an antipattern, for the following reasons: > > > 1. it interacts weirdly with inheritance and metaclasses; figuring out > whose __new__ is going to be called and why always turns into an advanced > calculus problem > 2. it has surprising behavior with respect to __init__ > 3. it tightly couples a specific way of initializing a particular > object with the residence of that object in memory. any object with an > asynchronous initializer can't be deserialized normally, for example, > because __new__ is now doing something surprising > 4. it makes testing harder, because now you can't even create a simple > test object without a whole event loop running > > > Fundamentally, object initialization is a *local* phenomenon. It's a > data structure that your program is using to think about the world. When > you "asynchronously initialize" something, you are doing two things: the > remote gathering of information which will initialize the object, and the > local construction and initialization. The former phase should be a method > (which can be a classmethod) and the latter is the object's constructor > itself. > > More broadly, having constructors do I/O is an anti-pattern for these same > reasons; you just notice it faster in an async framework :). > > -glyph > -- "I disapprove of what you say, but I will defend to the death your right to say it." -- Evelyn Beatrice Hall (summarizing Voltaire) "The people's good is the highest law." -- Cicero GPG Key fingerprint: 125F 5C67 DFE9 4084
