Reputation: 73
Take a sample program:
c = 10
def myfunc():
print(c)
myfunc()
This prints 10 as expected, but if we look at another program:
c = 10
def myfunc():
print(c)
c = 1
myfunc()
It says: local variable 'c' referenced before assignment
Here, if the python interpreter is actually going line by line, shouldn't it print 10
before reaching the next line to conclude there's a local variable?
Python has a lexer, tokenizer and parser. Does it go through all the code, parse it before executing them line by line?
Is that why it's able to say there's a local variable down the function?
Upvotes: 3
Views: 1677
Reputation: 2814
Before the interpreter takes over, Python performs three other steps: lexing, parsing, and compiling. Together, these steps transform the source code from lines of text into byte code containing instructions that the interpreter can understand. The interpreter's job is to take these code objects and follow the instructions.
So the error is produced by Python when it is translating the source code into byte code. During this step, scope is also decided. This is because the byte code will need to reference the correct variable locations. However, in this case, it is now wired to reference a variable that is not defined in the scope, causing the error at runtime.
In this snippet of code there are no syntax errors, no scope errors.
c = 10
def myfunc():
print(c)
myfunc()
In this program, the c = 1
implicitly makes the variable local. However, this is defined after the print(c)
which is not yet defined in its scope.
c = 10
def myfunc():
print(c)
c = 1
myfunc()
So if you did this:
c = 10
def myfunc():
c = 1
print(c)
myfunc()
or
c = 10
def myfunc():
global c # Changes the scope of the variable to make it accessible to the function
print(c)
c = 1
myfunc()
the code would work just fine.
To answer your question:
Does it go through all the code, parse it before executing them line by line?
Yes, it does.
Upvotes: 7
Reputation: 38
Miles C. is correct. I'd guess though from your code you are coming over from a structured language such as C or C++. Python won't reference variables the same way C or C++ does it needs to be told to do so. The global keyword tells python you are looking for the variable outside of the function.
Upvotes: 0
Reputation: 111
The problem is not the order of interpretation, which is top to bottom as you expect; it's the scope. In Python, when referencing a global variable in a narrower function scope, if you modify the value, you must first tell the code that the global variable is the variable you are referencing, instead of a new local one. You do this with the global keyword. In this example, your program should actually look like this:
c = 10
def myfunc():
global c
print(c)
c = 1
myfunc()
Upvotes: 1