Question about accessing class-attributes.

Alex Martelli aleax at aleax.it
Thu Apr 24 13:31:10 EDT 2003


On Thursday 24 April 2003 05:35 pm, Bjorn Pettersen wrote:
   ...
> > Personally, I'd define a custom metaclass for this purpose.  Maybe
> > I'm getting TOO familiar with those, but, it doesn't sound all that
> > complex at all to me...:
>
> [...]
>
> I would too, but just for fun I thought "how about an abstract base
> class?". Due to a 'thinko' I didn't consider that B wasn't calling its
> superclass __init__, so I came up with:
>
>   class AbstractBaseCounter(object):
>       __InstCount = {}
>       def InstCount(cls):
>           return AbstractBaseCounter.__InstCount[cls]
>       InstCount = classmethod(InstCount)
>
>       def __init__(self):
>           cls = self.__class__
>           if cls == AbstractBaseCounter:
>               raise TypeError("Attempt to instantiate abstract base
> class")
>           d = AbstractBaseCounter.__InstCount
>           if cls in d:
>               d[cls] += 1
>           else:
>               d[cls] = 1
>
>   class A(AbstractBaseCounter):
>       def __init__(self):
>           AbstractBaseCounter.__init__(self)
>
>   class B(A): pass
>
>   a1=A()
>   a2=A()
>   b1=B()
>   b2=B()
>   print B.InstCount()

comparing the complication of this one, and the simplicity of the custom
metaclass I posted and you snipped, PLUS the minor risks such as
"B overriding __init__ and forgetting to call its superclass's"(:-), I think
the custom metaclass is vindicated;-).

> which happens to work...? I've verified that
> AbstractBaseCounter.__init__ gets called for B(). Is this
> correct/documented/guaranteed/works with MI/multiple args/old-style
> classes, etc., etc.?

well, you COULD get dual calls to that __init__ in presence of
"inheritance diamonds" -- using super may be safer.


Alex






More information about the Python-list mailing list