Hacking with __new__

Duncan Booth duncan.booth at invalid.invalid
Tue Jul 24 04:53:01 EDT 2007


Sandra-24 <sandravandale at yahoo.com> wrote:

> So thinking myself clever with python I thought I could change
> S3ResponseError to have a __new__ method which returns one of the 30
> new exceptions. That way none of the raise S3ResponseError code needs
> changing. No problem. The trouble comes with those exceptions being
> subclasses of S3ResponseError, because __new__ is called again and
> goofs everything up.

I think what you want for Bar is something more along the lines:

class Foo(object):
    def __new__(cls, *args):
        print 'Foo.__new__', len(args)
        return super(Foo, cls).__new__(cls, *args)

    def __init__(self, a, b, c):
        print 'Foo.__init__', 3
        self.a = a
        self.b = b
        self.c = c

class Bar(Foo):
    def __new__(cls, a, b, c, *args):
        print 'Bar.__new__', len(args)
        target = cls
        if not args:
            cls = Zoo
        obj = super(Bar, cls).__new__(cls, a, b, c, *args)
        if args:
            return obj

        obj.__init__(a, b, c, 7)

class Zoo(Bar):
    def __init__(self, a, b, c, d):
        print 'Zoo.__init__', 4
        Foo.__init__(self, a, b, c)
        self.d = d

Bar(1,2,3)

Output from this is:

Bar.__new__ 0
Foo.__new__ 3
Zoo.__init__ 4
Foo.__init__ 3

Bar can instantiate a subclass, but to do that it wants to call the 
constructor __new__ only for the base classes, and because it has 
changed the type of the object being constructed it has to call __init__ 
explicitly.



More information about the Python-list mailing list