Unbound Local Error within multiple Functions [duplicate] - python

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 2 years ago.
I've been creating a series of random events where each function does something different to a main set of variables, yet I keep getting unbound local errors. Here's a watered down version of the barebones of my code
variable = 1
def main():
global variable
secondary()
variable = secondary()
def secondary()
variable += 1
return variable
once again this is a really minimal way to explain my code but the variable += 1 is the part that is expressing the error

I noted all of the same issues that #TimothyChen mentioned. I'd like to explain the error you're asking about, which is:
UnboundLocalError: local variable 'v' referenced before assignment
That happens here:
v = 1
def secondary()
v += 1
The issue here is due to a behavior that is unique to Python, and a little strange (please excuse that I changed the name variable to v to avoid confusion)...
If there is a global variable declared named v, and then you only read from a variable named v inside a function, Python declares that you are reading from the global variable named v.
If there is a global variable declared named v, and then you write to a variable named v inside a function, Python says that that's a different variable local to the function unless you first say global v in that function, after which point v refers to the global variable.
So the case of your function secondary(), you are A) writing to v in the function, and B) you don't say global v anywhere in the function. So Python says that inside that function, v is a unique variable local to that function. But if v is local to the function, and your first reference to the variable in that function is:
v += 1
then v hasn't been assigned a value prior to this point. Since this line of code first reads from v, and then writes a new value back to it, you get the error you're seeing because of the attempt to read from a variable that hasn't yet been assigned a value.
It seems pretty clear that what you need to do to fix this issue is to declare your secondary function as follows:
def secondary()
global variable
variable += 1
return variable
The addition of global variable tells Python that your reference to variable is referring to the global variable with that name, even though you are writing to it.
I would suggest that in the future, you not name variables variable. That can only lead to confusion.

In the secondary function, variable isn't defined. You would have to do global variable, which would make the variable accessible. Also, you call secondary twice, which would make the variable go up twice, not sure you would want that. Furthermore, secondary doesn't have a colon after the parentheses which creates a syntax error. Lastly, the code most likely isn't indented correctly, as the secondary variable is not indented, although the other code blocks are.

Related

How interpreter of Python recognize undefined global variable in function?

How interpreter of Python recognize undefined global variable (a) in function in the following code ?
def show():
print(a)
a = 1
show()
Python is interactive language, so it processes each line of code line by line.
Given this, it should throw an error at the line with undefined variable (print(a)).
However, it works without error.
How does interpreter of Python recognize the undefined variable (a) ?
Or is it just recognized as letters until show function is called?
I converted the above code to bytecode, but I didn't understand well it...
When you define your function inside a python interpreter, python treats it as a sort of black box. It initializes the variables that are not defined inside and outside the function as free variables. Then, it stores a reference to the function inside the global table (you can access it using globals()). This global table holds the values for global variables and global function references.
When you define the variable a python stores it inside the global dictionary as well. Just like the function before it.
After that when you call your function, python sees a variable a. It knows that the variable is free, therefore, must be declared inside the global variable by now. Then it looks up the global table and uses the value that is stored.
Python is run line by line, and in saying that, it will skip over the function until the function is called. So even though it's line by line, it's still running afterwards.
Use of global keyword:
To access a global variable inside a function, there is no need to use global keyword. As a is not assigned inside the function, python will look at the global scope.
We use global keyword to assign a new value to the global variable.
This example throws an error -
def show():
a = a + 5
print(a)
a = 1
show()
Error:
UnboundLocalError: local variable 'a' referenced before assignment

Printing the value of a global variable and then changing the value in python

The global keyword is used in a function to refer to a global variable within that function and modify it. However even if the global keyword is not used and if we just try to print the variable, python assumes it is the global variable that is being referred and simply prints that like so.
a = 2
def foo():
print(a)
foo()
the above code outputs 2. But the following code throws an error.
a = 2
def foo():
print(a)
a = 3
foo()
I get an UnboundLocalError saying local variable 'a' was referenced before assignment. Now since python is an interpreted language and execution happens one line at a time, shouldn't it first print the global value of a which is 2 (like in the first case) and then create a local variable with the same name ans assign it to 3. In the second case how does the interpreter know right at the print statement that I am referring to another variable 'a' in the next line? Why doesn't it behave in the same way as above?
PS: I do understand that using the global keyword can help me change the value of a from 2 to 3.
Python byte code is interpreted; Python source is first compiled to byte code.
Names are either local or global within a single scope, and that determination is made at compile time; you can't switch half way through a fuction. If there is any assignment to a in the function, it is local everywhere in the function unless you use global a.
a = 2
def foo():
global a
print(a)
a = 3
Without the global statement, print(a) refers to the local name a, even though it occurs before the actual assignment.

Scope in Python 3.6.And the Error [duplicate]

This question already has answers here:
Function not changing global variable
(4 answers)
Closed 5 years ago.
How does the code below give the output as None?
def funct(x):
x=7
x=11
x=test(x)
print(x)
Here is another code snippet:-
def func():
print (x)
x = 90
x = 1
func()
The output for this should be 90! The scope is searched as Local ,Enclosed , Global ,Build-in .Either x should here be searched as local or global
Please explain.
x here is not a global variable in the scope of the functions, as functions naturally create their own namespaces, which do not include any outer variables not passed in as a parameter.
There are many issues with your code, including the order of function calling, and the order of the operations inside the functions; but to answer your question in the broadest way possible, in order for you to access the x variable defined outside of your functions, in a greater scope that is, you need to reference its namespace, by prepending global x inside the body of each of your functions.
Read up on Python variables and scope, and recheck the other errors in your code I have stated above.
The first code snippet returns None for the simple fact that you didn't return any value from the function. You defined x as a local parameter, not a global variable. Since you didn't return any value, your call test(x) (which does not match the function name of funct), will become a value of None. This is clearly defined in the Python documentation. To get the local value back to your main program, try this:
test(x):
x = 7
return x
x = 11
x = test(x)
print(x)
Also, please note that your initial value of 11 is entirely ignored in the main program, and that your function ignores the value it's given. You should shorten this example to
func():
return 7
print(func())
Your second example will print the external value of 1 because you have not defined a local variable x at that point, and a function is allowed to reference global variables.
However, when you assign a value in the next, you create a local variable -- you have not declared x to be global, so you can't assign to the x in the main program.
Again, you do not return any value. Therefore, back in the main program, func() evaluates to None.
Does that clear up what happened?

Why 4 is returned for the follow code in Python [duplicate]

This question already has answers here:
Short description of the scoping rules?
(9 answers)
Closed 8 years ago.
>>> a = 10
>>> def f(x):
return x + a
>>> a = 3
>>> f(1)
According to my experience on Java, the definition of f contains a local variable a, but how could the global binding a been visible on the function f call stack environment?
I did a research on the python syntax and found that's true, could anybody offer some background on why python dealing variable scope this way? thanks.
Your function call is in the last line.
When the function gets called, python first looks up for local variables with name a,
if not found, it goes into global scope, and in global scope, the last assigned value of a is 3 ( just before the function was called)
What you may find even stranger is that this will also work:
>>> def f(x):
return x + a
>>> a = 3
>>> f(1)
Note that a hasn't even been defined before the function f. It still works because your call to f is after a is defined and placed in the global namespace. At that point, since f does not have a in its local namespace, it will fetch it from the global namespace.
You can fetch the contents of the global namespace and check for yourself with globals(), and the local namespace with locals(). There's also some neat tricks you can do by manipulating the namespaces directly, but that is in most cases considered bad coding practice in Python, unless you really have a compelling reason and know what you're doing.
It would return 4 because you declare a and f(x) a function then you give valuea=3 and then you give x=1 so the function would return 3+1 which is 4
Python decide variable scope in function based on where they have been assigned. As you didn't assigned variable 'a' inside function so it starts looking out and consider the global value.
In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a new value anywhere within the function’s body, it’s assumed to be a local. If a variable is ever assigned a new value inside the function, the variable is implicitly local, and you need to explicitly declare it as global.
Ref : http://effbot.org/pyfaq/what-are-the-rules-for-local-and-global-variables-in-python.htm
Java is a purely object-oriented language, while Python is not. Python supports both structural as well as object-oriented paradigms.
Global variables are part of the structural programming paradigm. So global variables will be available in the scope of a function, unless another variable with exactly the same name exists in the local scope of that function.

Python scope, dictionary and variables difference? [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Why isn't the 'global' keyword needed to access a global variable?
(11 answers)
Closed 6 months ago.
Python scope
I have the same question but slightly different.
number = 0
def incrementNumber():
number += 1
This one above does not work but this one below does why? Both are outside the function scope.
number = {'num':0}
def incrementNumber():
number['num'] += 1
First one works if I add the variable as global
number = 0
def incrementNumber():
global number
number += 1
Check out this blog post, it's similar to what you're doing. Specifically adam's comment.
You don't assign to dictionaryVar, you assign to dictionaryVar['A'].
So it's never being assigned to, so it's implicitly global. If you
were to actually assign to dictionaryVar, you'd get the behavior you
were "expecting".
In the first case int is not mutable, so when you do number +=1 your are really updating where number points. As you, in general, do not want changes to propagate up-scope with out
explicitly telling it to, python does a copy-on-write and gives you a local variable number. You than increment that variable and it is thrown away when the function returns
In the case of dictionaries, which are mutable, you are grabbing the up-scope reference and then mutating the underlying object, thus your addition propagates out of the function.
In the last case you have explicitly told python to not make number a local variable, thus the changes propagate out as you want.
related python closure local variables

Categories