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