Class-level variables - a scoping issue

Jonathan Gardner jgardner at
Sun Oct 10 09:10:46 CEST 2010

On Oct 9, 10:30 pm, John Nagle <na... at> wrote:
>     Here's an obscure bit of Python semantics which
> is close to being a bug:
>  >>> class t(object) :
> ...     classvar = 1
> ...
> ...     def fn1(self) :
> ...         print("fn1: classvar = %d" % (self.classvar,))
> ...         self.classvar = 2
> ...         print("fn1: classvar = %d" % (self.classvar,))
> ...
> ...

You don't quite understand the intricacies of Pythonese yet. It's
really simple, which isn't a common feature of most programming

    class T(object):
        classvar = 1

means: Create a class which has an attribute "classvar" initialized to
1. Assign that class to "T".

"self.classvar" means: Lookup the value for 'classvar' in 'self',
visiting its class and parent classes if you can't find it.

"self.classvar = 2" means: Create or replace the attribute 'classvar'
of 'self' with 2.

Notice how the two meanings are quite different from each other?

Fetching an attribute means something different than assigning to it.
Python doesn't remember where the attribute came from when assigning---
it simply assigns at the top level.

If you wanted to, instead, change T's classvar, then you need to be
explicit about it and write "T.classvar = 2".

More information about the Python-list mailing list