If I have a function like this:
x = 10
def foo():
print(x)
x = 20
print(x)
Calling foo throws an UnboundLocalError
at first print
. So it looks like the symbol table is constructed at parse time. But this is inconsistent with name resolution for class variables.
For example:
x = 10
class A:
print(x)
x = 20
print(x)
prints 10
and 20
. So the symbol table for the class is updated while its running.
The same thing goes for member variables.
class A:
x = 10
def foo(self):
print(self.x)
self.x = 20
print(self.x)
a = A()
a.foo()
prints 10
and 20
. The symbol table for the instance is again updated at runtime. The first print(self.x)
does not throw just because there's an assignment to it later.
What is the rationale behind this inconsistency? Why doesn't the symbol table for functions get updated at runtime instead? Is it purely for performance reasons?