0

I'm just curious how python know beforehand that a variable is local and not reference the global variable instead. Please have a look on two versions of the code.

eggs = 'global'
def spam():
    print(eggs)
    eggs = 'local'
spam()

While, if i comment eggs = 'local', python refer to global variable.

eggs = 'global'
def spam():
    print(eggs)
    # eggs = 'local'
spam()

Please help me with understanding as to what i'm missing.

Edit: Found the answer here: Python variable scope error

1 Answers1

1

How exactly Python does this is an implementation detail but the key is, "interpreted" doesn't mean it scans every line in order and knows nothing about the next line. If that were the case, every code until a syntax error would be run. Python analyzes the entire code to make sure it is valid code before running it.
The rule is, if a name is assigned in the local scope, referencing it before the assignment is an error, even if that name is defined in an outer scope.

Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • 1
    That's not true. You want to change *referencing* to *assigning*. If for example said variable is a list and you're appending to it, that will pass with no errors – Tomerikoo Aug 12 '19 at 19:18
  • 1
    By referencing I meant using that name. – Aykhan Hagverdili Aug 12 '19 at 19:19
  • Since python is interpreted. How does it know beforehand that i created the same local variable? – Himanshu Gangwar Aug 12 '19 at 19:21
  • "If for example said variable is a list and you're appending to it, that will pass with no errors" I tried and it failed. Can you show what you mean in a small example? – Aykhan Hagverdili Aug 12 '19 at 19:21
  • 5
    @HimanshuGangwar interpreted doesn't mean it scans every line in order and knows nothing about the next line. If that were the case, every code until a syntax error would be run. Python scans the entire code to make sure it is valid code before running it – Aykhan Hagverdili Aug 12 '19 at 19:23
  • Is obviously hard to post code here but that one is simple. Two lines function there: `a = [1] def foo(): print(a) a.append(2) foo() ` – Tomerikoo Aug 12 '19 at 19:24
  • 1
    “Interpreted” doesn’t necessarily mean there is no analysis of the function as a whole before it is executed. – DisappointedByUnaccountableMod Aug 12 '19 at 19:24
  • 1
    @Tomerikoo that doesn't have the problem I am explaining. It works because you don't declare `a` as a local variable. An example similar to what you said could be `a = [] def f(): a.append(1); a = 1`, which fails. – Aykhan Hagverdili Aug 12 '19 at 19:26
  • 1
    @Ayxan I got the point and my confusion. The nail in your answer is *if a name is declared in the local scope*. In that case completely right. My bad :) – Tomerikoo Aug 12 '19 at 19:28
  • Python doesn't have variable declarations. You mean assignment – juanpa.arrivillaga Aug 12 '19 at 19:29
  • @Ayxan This solves my problem. As you said, there are phases of executing the code. So, that's how compiler know beforehand that there is a local variable. Got the answer here. https://stackoverflow.com/questions/370357/python-variable-scope-error – Himanshu Gangwar Aug 12 '19 at 19:34
  • @HimanshuGangwar CPython is compiled to bytecode and then the bytecode is interpreted. – juanpa.arrivillaga Aug 12 '19 at 19:35
  • @juanpa.arrivillaga, Alright. So, the bytecode conversion phases actually tells the machine that 'there's a local variable too' and hence while execution 'you are referencing it before assignment'. Thanks for the information. – Himanshu Gangwar Aug 12 '19 at 19:43