Class-level variables - a scoping issue

John Nagle nagle at animats.com
Sun Oct 10 01:30:43 EDT 2010


    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,))
...
...
 >>> t1 = t()
 >>> t2 = t()
 >>> t1.fn1()
fn1: classvar = 1
fn1: classvar = 2

 >>> t1.fn1()
fn1: classvar = 2
fn1: classvar = 2

 >>> t2.fn1()
fn1: classvar = 1
fn1: classvar = 2

     Notice what happened here.  Within "fn1", the first
reference to "self.classvar" references the class-level
version of "classvar".  The assignment overrides that
and creates an object-level instance of "self.classvar".
Further references to "self.classvar" in f1 then reference the
object-level "classvar"

     Creating another instance of t makes it clear that the
class-level variable never changes.   To change it, it
has to be referenced as "t.classvar".

     Python protects global variables from similar confusion
by making them read-only when referenced from an inner scope
without a "global" statement.  But that protection isn't
applied to class-level variables referenced through 'self'.
Perhaps it should be. 	

				John Nagle



More information about the Python-list mailing list