0

Trying to understand Python static variables, and the following confuses me:

>>> class Foo():
...     a = [1]
... 
>>> f = Foo()
>>> Foo.a.append(2)
>>> Foo.a
[1, 2]
>>> f.a
[1, 2]
>>> f.a.append(3)
>>> f.a
[1, 2, 3]
>>> Foo.a
[1, 2, 3]
>>> # appears that Foo.a and f.a reference same list object
... 
>>> Foo.a = 3 
>>> f.a
3
>>> Foo.a
3

Based on the top answer to this question (Static class variables in Python), I would expect that Foo.a and f.a are separate names, but that f.a is just first initialized to Foo.a. This explanation works if you first try to modify the object through Foo.a or reassign f.a, but I am confused by the last few lines. I would expect Foo.a = 3 to only reassign Foo.a, but it seems to have reassigned f.a as well, as it is no longer referencing the list object. If you assign to f.a first, reassignment of Foo.a does not change f.a, so it seems f.a is syntatic sugar for Foo.a until f.a is explicitly assigned to. Is this correct?

Community
  • 1
  • 1
Kerry
  • 115
  • 1
  • 7

1 Answers1

2

I wouldn't call it syntactic sugar. Rather, it's a consequence of the name lookup order in Python scopes.

Given an instance, Python will first attempt to look up a name on that instance. If that fails, it will fail back to looking it up in the class. This is what is happening in your case; at first, the name does not exist on the instance, so the lookup refers to the class attribute. As soon as an instance variable is defined, the name will refer to that.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895