0

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?

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
wingerse
  • 3,670
  • 1
  • 29
  • 61
  • Related [Python variable scope error](https://stackoverflow.com/questions/370357/python-variable-scope-error) ... [Why the difference in handling unbound locals in functions versus classes?](https://stackoverflow.com/questions/48638633/why-the-difference-in-handling-unbound-locals-in-functions-versus-classes), ... https://stackoverflow.com/a/23471004/2823755 – wwii Aug 29 '19 at 18:42
  • ... [Function closure vs. callable class](https://stackoverflow.com/questions/8966785/function-closure-vs-callable-class). Maybe a duplicate in there somewhere? – wwii Aug 29 '19 at 18:54
  • The third example has nothing to do with the other two. There you simply have a class attribute which is subsequently shadowed by an instance attribute. – Daniel Roseman Aug 29 '19 at 19:12

0 Answers0