Question about accessing class-attributes.

Michele Simionato mis6 at pitt.edu
Fri Apr 25 00:14:26 CEST 2003


Duncan Booth <duncan at NOSPAMrcp.co.uk> wrote in message news:<Xns93679D1BF4A2Cduncanrcpcouk at 127.0.0.1>...
> Alex Martelli <aleax at aleax.it> wrote in 
> news:EARpa.120$3M4.2728 at news1.tin.it:
> 
> > ..isn't this smoother and handier?  Or does it just look that way
> > to me, due to overexposure to custom metaclasses?-)
> > 
> Yes, I agree that it is better, but I have one niggling worry about this:
> 
> Your metaclass works fine for the one requirement given here, and other 
> metaclasses you have proposed work fine in their place, but 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.

My motivation for multiple inheritance from a class and a metaclass was
the counting of classes, since I had a Counter class:

class Counter(object): 
    counter=0  
    def __new__(cls,*args,**kw):
        cls.counter+=1 
        return super(Counter,cls).__new__(cls,*args,**kw)  

and I promoted it to a metaclass as follows:

class MetaCounter(Counter,type):
      pass

The subtle problem does not appears here but in complications of this
pattern. I would advice against this pattern, also because type.__new__
is not cooperative with Counter.__new__  and 

class MetaCounter(type,Counter):
      pass

would not work.

HTH,

                            Michele




More information about the Python-list mailing list