Class variable inheritance

Chris Rebert clp2 at rebertia.com
Tue Sep 8 04:53:20 CEST 2009


On Mon, Sep 7, 2009 at 7:21 PM, Henry 'Pi' James<henrypijames at gmail.com> wrote:
> I've just found out that a subclass shares the class variables of its
> superclass until it's instantiated for the first time, but not any
> more afterwards:
>
> Python 3.1 (r31:73574, Jun 26 2009, 20:21:35) [MSC v.1500 32 bit
> (Intel)] on win32
> Type "help", "copyright", "credits" or "license" for more information.
>>>> class A:
> ...   n = 0
> ...   def __init__(self):
> ...     type(self).n += 1
>>>> class B(A):
> ...   pass
<snip>
> This makes no sense to me at all. Could it possibly be a bug?

Makes sense to me. To step through what's happening:

>>> A.n, B.n
(0, 0)

Here, the lookup on B.n fails (that is, B itself has no variable n),
and thus falls back to A.n
Thus, at this point, the expressions `A.n` and `B.n` are equivalent.

>>> (A().n, A.n, B.n)
(1, 1, 1)

A.__init__() gets called, incrementing A.n; again, B.n falls back to A.n

>>> (A().n, A.n, B.n)
(2, 2, 2),

<same thing>

>>> (B().n, A.n, B.n)
(3, 2, 3)

A.__init__() gets called since B did not define one of its own and
this inherited A's.
Therein, type(self) evaluates to B (not A as before).
B.n += 1 is in this case equivalent to:
B.n = B.n +1
Evaluating the right side, B.n falls back A.n once again, and we add 1.
Now the assignment takes place, creating a new variable B.n, *separate* from A.n
>From hereon in, lookups of B.n don't fall back to A.n since B now has
its own variable 'n'.
Thus, the values of A.n and B.n differ and the expressions now refer
to 2 distinct variables.

The rest falls out from this and is left as an exercise for the reader.

Cheers,
Chris
--
http://blog.rebertia.com



More information about the Python-list mailing list