On 7 April 2011 15:36, Nick Coghlan <ncoghlan@gmail.com> wrote:
On Thu, Apr 7, 2011 at 11:48 PM, Michael Foord <fuzzyman@gmail.com> wrote:
> Hmmm... that would rely on subclass.__new__ both existing *and* not calling
> up to its parent __new__ or you will have infinite recursion.
> Probably what you have to do is call object.__new__(subclass, ...) and
> knowing / praying that subclass.__new__ doesn't do anything important...

That's the dance I'm trying to remember. You make it work by playing
identity checking games with the cls argument, but it's been
absolutely ages since I read about it and experimented with it.

I think it's something like:

def __new__(cls, *args, **kwds):
 if cls is ThisClass:
   # Do fancy footwork to implicitly create an appropriate subclass instead
   # via subclass.__new__
   obj = cls._create_instance(*args, **kwds)
 else:
   # Don't do anything tricky for subclasses, that's their problem
   obj = object.__new__(*args, **kwds)
 return obj

Subclasses then have the option of passing the parent class as "cls"
if they want to invoke the fancy footwork, or themselves if they
don't.


Nice solution. You should write it up on your blog. It lets you call subclass.__new__, to return instances of subclasses, without having to worry about whether or not subclass.__new__ is going to upcall.

Michael
 
Cheers,
Nick.

--
Nick Coghlan   |   ncoghlan@gmail.com   |   Brisbane, Australia



--
http://www.voidspace.org.uk/

May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing http://www.sqlite.org/different.html