> I think the line "The first time _incr executes, the try
> block fails, since _count has not yet been made an
> attribute of the class object ..." is incorrect and
> confuses class attributes with instance (data) attributes.
> Class attributes can be accessed before an instance of the
> class is created.
Yes, but that's not the point. There is no
_count
attribute for the derived classes
Point
or
Line
until they are bound dynamically.
> I don't see the need to check for AttributeError when you
> have already initialised _count to 0.
>
> You can simply use:
>
> class Shape(object):
> _count = 0 # A shared value for Shape classes with no
> h no current objects
>
> @classmethod
> def _incr(cls):
> cls._count += 1
But I haven't initialized
Point._count
to 0! You will get an
AttributeError
because
Point._count
does not exist. I am not incrementing
Shape_count
, but rather
Point._count
(which is created in the exception handler), and then
Line._count
, etc., through the
cls
variable. I wonder if you get my point. There are three variables named
_count
by the time the code snippet in the article runs. Your "simplification" does not solve the same problem I did - it is only keeping a single count for the whole hierarchy. I am keeping a separate count for each subclass. And there are no instance attributes anywhere in this example. If you trace through the C++ version, you will see what is being accomplished here.