2

This is the challenge:

x = 11
def foo1():
  x = 2
  class foo:
    print(x)
foo1()  # prints 2

x = 11
def foo2():
  x = 2
  class foo:
    print(x)
    x += 1
foo2()  # prints 11

What is the explanation of this behaviour? Anyone?

mavaras
  • 53
  • 5
  • It's the fact that it's being assigned; when you assign it to a value, the one in the scope of `foo` is not used. When you don't, the one within the scope of `foo` is used. I haven't been able to tell why yet, though. – Random Davis Feb 19 '22 at 00:03
  • 1
    Yeah, see the linked duplicate. This is a weird edge case in python. Class blocks are special in a couple of respects. In particular,[looking at the execution model reference, the name resolution section](https://docs.python.org/3/reference/executionmodel.html#resolution-of-names), "unbound local variables are looked up in the global namespace.". So normally, if this were a nested function, it would raise an *unbound local error*, because `x += 1` would be referencing a local, `x` without it being defined. Instead of raising an error, a class block will check the global scope! – juanpa.arrivillaga Feb 19 '22 at 00:09
  • Note, people often ... take advantage of this quirk by doing something like `foo = foo` inside the class, taking the value of a global variable for a class-level variable. – juanpa.arrivillaga Feb 19 '22 at 00:14
  • @RandomDavis so, when it isn't being assigned, the compiler treats it as a free variable, and it goes through the normal [name resolution process](https://stackoverflow.com/questions/291978/short-description-of-the-scoping-rules). – juanpa.arrivillaga Feb 19 '22 at 00:20

0 Answers0