Question about accessing class-attributes.

Michele Simionato mis6 at pitt.edu
Mon Apr 28 19:31:52 CEST 2003


mis6 at pitt.edu (Michele Simionato) wrote in message news:<2259b0e2.0304241414.675b1e14 at posting.google.com>...
> Duncan Booth <duncan at NOSPAMrcp.co.uk> wrote in message news:<Xns93679D1BF4A2Cduncanrcpcouk at 127.0.0.1>...

> > <snip> what happens if 
> > you want to combine these and get e.g. a Bunch which counts its instances?
> > 
> > I haven't tried it to see what happens, maybe you just need to indirect 
> > type.__new__ calls through super, and make a new submetaclass with the old 
> > metaclasses as bases, but I'd like to know if there are issues here or if 
> > I'm just worrying needlessly.
> 
> I did quite a lot of experiments on multiple inheritance of metaclasses,
> and as far as I can tell it works quite well. You should not worry, except
> in the case in which you want to multiple inherits from a metaclass and
> a normal class by redefining __new__. Then I have found a nasty subtility
> that made me loose an afternoon. You can find the solution if you Google
> on the newsgroup under "another super wart" (read only my last post, the
> first was wrong). This only happens in very complicate hierarchies, anyway.

I take back what I said. I have just downloaded Python 2.3b1 and discovered
the the super bug I was talking about has been fixed!
Now the following script will work as expected:

"Super bug fixed in 2.3b"

class Counter(object):
    counter=0 
    def __new__(cls,*args,**kw):
        cls.counter+=1; print "Creating instance #%s of %s" % (
            cls.counter,cls)
        return super(Counter,cls).__new__(cls,*args,**kw)

class MetaCounter(Counter,type):
    pass 

class C(Counter): #=> Creating instance #1 of <class '__main__.MetaCounter'>
    __metaclass__=MetaCounter

C() #=> Creating instance #1 of <class '__main__.C'>

assert super(Counter,C).__new__ is object.__new__ # True in 2.3
# assert super(Counter,C).__new__ is type.__new__  # True in 2.2

This works in Python 2.3b, where the superclass of Counter with respect to
the MRO of C is object; does not work in previous versions, where super
computes the superclass of Counter with respect to the MRO of
type(C)=MetaCounter, which is type and the script would raise a
TypeError: type.__new__(C): C is not a subtype of type

Now super retrieves correctly even properties therefore I would say it
works pretty nice. At this point, there is little reason to wonder about 
using multiple inheritance and metaclasses ;)



                                Michele




More information about the Python-list mailing list