Why does python behave this way with variables?

I am trying to understand why python behaves this way in the code block below. I did my research, but could not find a good answer, so I came here to find out if someone can point me in the right direction or give a good explanation. I understand that this is due to some old ALGOL principle, but I do not quite understand this.

var = 5 def func1(): print(var) func1() def func2(): var = 8 print(var) func2() def func3(): print(var) var = 8 func3() 

The result of this code is as follows:

5
8
UnboundLocalError: local variable 'var' referenced before assignment

I understand why we get outputs "5" and "8". But with "func3 ()" I was expecting to exit "5". It seems that the interpreter believes that I want to print the local "var" in the function instead of the global "var". Thus, this generates this error.

Or maybe if the variable is defined somewhere inside the function, then the function will use the local variable by default, not the global one with the same name.

But why exactly is python behaving like this? I'm not complaining, I'm just trying to figure something out ...

How can I use a predefined global variable in a function and then define a local variable with the same name inside the same function without changing the value of the global variable? (of course in python)

Thanks in advance to everyone. You are amazing people! :)

Edit_1: Thanks everyone for the great answers. I fully understand that it is a bad and impractical idea to use a predefined global variable in a function and then define a local variable with the same name inside the same function. I just thought about it from a theoretical point of view, because I saw it at a lecture in college. XD I can not find a single use case in which it would be optimal to do this!

Edit_2: I already read PEP8, and I know that being explicit is better than being implicit. :) That's true. Otherwise, the code will be confusing and lead to errors. This question was about some sort of useless and impractical college theory that I was trying to understand.

Edit_3: Now I fully understand why this is happening and what is happening here. Thanks to Randall Valenciano for providing this blog link which explains this very well.

What happens is that the function is interpreted as a whole, and not line by line. Therefore, when a function is interpreted, variable declarations of any defined variables move to the beginning of the function. Therefore, when we print "var", the function uses a locally declared variable that has not yet been assigned a value, and then the interpreter complains about it and throws it wrongly.

Thanks to all of you again! :) You really helped me! Now I finally understand what is happening there under the hood.

+7
source share
2 answers

Your var defined as a global variable. In each function, when you just read var , you get access to the global var, but the moment var assigned somewhere in the function, python treats each var inside the function as a local variable, so why is your last function did not work because print(var) (local varaible) was called before var = 8 was assigned.

In these threads you can read a little more:
How bad are shadow names defined in external areas?
Python nonlocal statement

The best thing to do is to explicitly specify your code so that it is not embarrassed if you are trying to reference a local, non-local or global variable.

In this case, if you intend to continue using the global var, do the following:

 var = 5 def func1(): print(var) func1() def func2(): global var var = 8 print(var) func2() def func3(): global var print(var) var = 8 # technically this is not necessary any more var = 8 was already assigned when func2() is called func3() 

The output signal in this way:

 5 8 8 

Edit: thanks juanpa.arrivillaga comment - I missed your original question.

How can I use a predefined global variable in a function, then define a local variable with the same name inside the same function without changing the value of the global variable? (in python, of course)

Short answer: first define the local var , as you did in func2() , and you are good. However, the longer answer is - why do you want to do this? This creates confusion and becomes a headache to keep track of when there are variables with the same name in different areas. A better approach is to indicate that your local var should be local_var or something that is distinctly different and easy to track.

+9
source share

Here is the rule for resolving Python Scope from this answer

LEGB rule.

L, Local - Names assigned in some way inside the function (def or lambda) and are not declared global in this function.

E, LANs - the name in the local area of โ€‹โ€‹all and all statically closing functions (def or lambda), from internal to external.

G, Global (module) - Names assigned at the top level of the module file, or the execution of the global operator in def in the file.

B, built-in (Python) - names assigned in the built-in name module: open, range, SyntaxError, ...

So, basically in your question, the resolution of the scope is โ€œinsideโ€, and since you are not using the global , the interpreter does not know to look outside the scope of a local function to find this var variable. The entire interpreter sees that you are using a variable before declaring and defining it, thereby throwing an error. Global variables are often dangerous, so Python wants to make sure you know you want to use a global variable, forcing you to be explicit.

See this other answer for an explanation of the global

Hope this helps.

+5
source share

All Articles