3

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?

krmogi
  • 2,588
  • 1
  • 10
  • 26
Keerthi Vasan
  • 63
  • 1
  • 7
  • 2
    All of your Python gets compiled to bytecode before execution starts - any syntax errors will prevent your code from running at all, and scope has to be decided in this compilation step as well (since the bytecode will need to reference the correct variable locations). – Grismar Dec 29 '21 at 03:11
  • 1
    "Interpreter" doesn't imply "line by line". Nothing says an interpreter has to execute a line before reading the next. – user2357112 Dec 29 '21 at 03:15
  • 1
    (And even if it did imply that, Python has to read the whole function definition before it reaches the line that calls the function.) – user2357112 Dec 29 '21 at 03:16
  • “[C]Python has a lexer, tokeniser and parser. Does it go through all the code, parse it before executing [the bytecode]" — yes, it does. – user2864740 Dec 29 '21 at 03:18
  • Does this answer your question? [Python Compilation/Interpretation Process](https://stackoverflow.com/questions/3299648/python-compilation-interpretation-process) – sahasrara62 Dec 29 '21 at 03:36
  • Thank you guys, I think I understand now – Keerthi Vasan Dec 29 '21 at 04:33

3 Answers3

6

Introduction

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.

enter image description here

Why?

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.

Examples

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.

Conclusion

To answer your question:

Does it go through all the code, parse it before executing them line by line?

Yes, it does.

krmogi
  • 2,588
  • 1
  • 10
  • 26
1

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()
Miles C.
  • 111
  • 4
  • Thank you for your reply, I am afraid that's not my question. I know about the global keyword and why it's used. It was just an example. My question was how python interprets a given file – Keerthi Vasan Dec 29 '21 at 04:29
0

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.

Diconica
  • 38
  • 5