Why does this code work:
var = 0
def func(num):
print num
var = 1
if num != 0:
func(num-1)
func(10)
but this one gives a "local variable 'var' referenced before assignment" error:
var = 0
def func(num):
print num
var = var
if num != 0:
func(num-1)
func(10)
Because in the first code, you have created a local variable var and used its value, whereas in the 2nd code, you are using the local variable var, without defining it.
So, if you want to make your 2nd function work, you need to declare : -
global var
in the function before using var.
def func(num):
print num
var = 1 <-- # You create a local variable
if num != 0:
func(num-1)
Whereas in this code:
def func(num):
print num
var = var <--- # You are using the local variable on RHS without defining it
if num != 0:
func(num-1)
UPDATE: -
However, as per #Tim's comment, you should not use a global variable inside your functions. Rather deifine your variable before using it, to use it in local scope. Generally, you should try to limit the scope of your variables to local, and even in local namespace limit the scope of local variables, because that way your code will be easier to understand.
The more you increase the scope of your variables, the more are the chances of getting it used by the outside source, where it is not needed to be used.
If you have var = ... anywhere in a function, the name "var" will be treated as a local variable for the entire function, regardless of where that assignment occurs. This means that all occurrences of var in your function will be resolved in the local scope, so the right hand side of var = var results in the referenced before assignment error because var has not yet been initialized in the function's scope.
You can read a global without declaring it global. But to write a global, you need to declare it global.
In your second piece of code you have created a local variable in RHS and without defining it, you are assigning it to the LHS variable var which is global (a variable defined outside the function is considered global explicitly).
If your intention is to create a local variable inside the function and assign it to the value of the global variable, this will do the trick:
var = 0
def func(num):
print num
func.var = var # func.var is referring the local
# variable var inside the function func
if num != 0:
func(num-1)
func(10)
def runscan(self):
p = os.popen('LD_PRELOAD=/usr/libv4l/v4l1compat.so zbarcam
/dev/video0','r')
def input(self):
self.entryc.insert(END, code)
how about this?
i want use local 'code' to the next function to insert the result of barcode to my Tkinter entryBox..
Thanks
Each function block is a local scope. If you want to assign to global variables, you need to do so explicitly:
var = 0
def func(num):
print num
global var
var = 1
if num != 0:
func(num-1)
print var # 0
func(2)
print var # 1
Related
This is what I want to achieve
Variable=0
Some_function(Variable)
print (Variable)
I want the output to be 1 (or anything else but 0)
I tried using global by defining some_function like this, but it gave me an error "name 'Variable' is parameter and global"
def Some_function(Variable):
x=Variable+1
global Variable
Variable=x
You are using Variable as your global variable and as function parameter.
Try:
def Some_function(Var):
x=Var+1
global Variable
Variable=x
Variable=0
Some_function(Variable)
print (Variable)
You should not use the same name for parameter and the globale variable
The error message seem clear enough. Also, you wouldn't need to pass Variable as a parameter if you are using a global.
If you define
def f():
global x
x += 1
Then the following script should not output an error :
x = 1 # global
f(x)
print(x) # outputs 2
Another possibility :
def f(y):
return y+1
Which you can use like this :
x = 1
x = f(x)
print(x) # 2
If you want to modify global variable, you should not use that name as function parameter.
var = 0
def some_func():
global var
var += 1
some_func()
print(var)
Just use global keyword and modify variable you like.
Variable = 0
def some_function(Variable):
global x
x = Variable + 1
some_function(Variable)
Variable = x
print(Variable)
I am making a system that reads a file, moves it to a new file, and moves it back with a new variable at the end of each line.
It is saying that linesRead is referenced before assignment
import random
handVar = 0
handList = []
linesRead = 'test'
def dealCards(numPlayers, cardList):
random.shuffle(cardList)
for i in range(0, numPlayers):
poppedCard1=cardList.pop()
poppedCard2=cardList.pop()
hand = (poppedCard1 + ', ' + poppedCard2)
handList.append(hand)
cardFile = open('players.txt', 'r')
playerLines= cardFile.readlines()
cardFile.close()
for i in playerLines:
for f in i:
linesRead = linesRead + f
print(linesRead)
tempFile = open('tempFile.txt', 'w')
tempFile.write(playerLines)
tempFile.close
tempFile = open('tempFile.txt', 'r')
playerFile = open('players.txt', 'a')
for i in tempFile:
newLine= (i + ', ' + handList[handVar] + ', ' + handList[handVar+1])
playerFile.write(newLine)
handVar = handVar + 2
The reason for the error scopes of the variables.
You are defining the variable linesRead in the global scope (outside of the function). It is available inside the function as long as you do not try to reassign the variable. When you reassign, Python treats is as a local scope variable (the scope of the function), and since you are using it in the reassignment, it is not able to find the assignment of that var in local scope.
Let's look at the following examples:
num = 42
def foo():
print(num)
foo()
Output:
42
In this case num is a variable defined in the Global scope (aka. module scope). It is defined at the top level of the module and is available in the local scopes of functions.
But the things are different in the following example:
num = 42
def foo():
print(num)
num = 12
foo()
Output:
UnboundLocalError: local variable 'num' referenced before assignment
What happens in this case is Python making the num a variable of the local scope of the foo function. That is it has nothing to do with the num of the global scope. Since I'm trying to print it before I assign it a value, it gives me an error.
Things are different when I move the assignment above of the print function call:
num = 42
def foo():
num = 12
print(num)
foo()
Output:
12
Same happens in this case, but since num is already assigned in the local scope by the time I'm calling the print, it won't error.
Solution
One of the solutions is to include the var as a global in the function. Something like this
def dealCards(numPlayers, cardList):
global linesRead
it will make the var from global variable available at the local scope.
But in this case if you modify the var in the function, the one at the module level will be changed as well
num = 42
def foo():
global num
print(num)
num = 12
foo()
print(num)
Output
42
12
Here is a fine, detailed read on Python scopes:
https://realpython.com/python-scope-legb-rule/
I have this code:
with open("01-1-input.txt", "r") as f:
inputs = [int(i[:-2] if i[-1] == "n" else i) for i in f.readlines()]
total_mass = 0
def calculate_fuel_for_mass(mass):
fuel_for_mass = mass // 3 - 2
if fuel_for_mass > 0:
total_mass += fuel_for_mass
calculate_fuel_for_mass(fuel_for_mass)
else:
return 0
for i in inputs:
calculate_fuel_for_mass(i)
print(total_mass)
And it's throwing an UnboundLocalError: local variable 'total_mass' referenced before assignment.
Why is that? I thought any variable declared in the main scope is global?
The line
total_mass += fuel_for_mass
can be thought of as equivalent to
total_mass = total_mass + fuel_for_mass
Given a setup like this, python sees an assignment happening to a variable in local scope (inside the function).
A minimal demonstration of this behaviour can be seen as follows:
var = 42
def f():
var = var + 1
# var += 1 would also show the same behaviour
f() #UnboundLocalError: local variable 'var' referenced before assignment
Python infers that there is a local variable total_mass because it sees an assignment to the variable in the local scope.
However, the local variable total_mass has not been assigned a value,
and so you see the error as shown.
You can use the global keyword before the assignment to access the variable in the global scope as follows
var = 42
def f():
global var
var = var + 1
f() #var is now 43 in global scope
At the beginning of your function, put
global total_mass
For this, you have to know how variable scopes and mutable/immutable types in Python work. The int type is immutable, so when you try to "modify" it in the function, you essentially create a new variable with local scope. As the compiler can see that the variable is going to be local to the function, it assumes that you want to access the local variable in the first place, rather than the global one. It is possible to declare the variable global using the global keyword, however it's considered bad practice, as the program becomes harder to read and to debug.
This question already has answers here:
Global dictionaries don't need keyword global to modify them? [duplicate]
(2 answers)
Why is the global keyword not required in this case? [duplicate]
(1 answer)
Closed 2 years ago.
I have declared a dictionary globally and a variable as well. Now, when accessing both in a class, I can access the dictionary but for accessing the other variable, I get the UnboundLocalError. For solving this, I used the line of code: global curr_length and then access it and it ran. But I wanted to known why is this additional line of code required for a normal integer variable whereas not required for a dictionary?
The code is:
memoized = {}
curr_length = 0
curr_pal = ""
class Solution:
def check_palindrome(self, str_):
if len(str_) <= 1:
return False
global curr_length
if len(str_) <= curr_length:
return False
if memoized.get(str_, None):
return memoized[str_]
if str_ == str_[::-1]:
memoized[str_] = True
curr_length = len(str_)
return True
memoized[str_] = False
return False
def longest_palindrome(self, str_, starting_index):
if len(str_) <= 1:
return None
n = len(str_)
if self.check_palindrome(str_[starting_index:n]):
return str_
n -= 1
self.longest_palindrome(str_[starting_index:n], starting_index)
def longestPalindrome(self, s: str) -> str:
for starting_index in range(len(s)):
pal = self.longest_palindrome(s, starting_index)
if pal:
return pal
return ""
solution = Solution()
print(solution.longestPalindrome("babad"))
Short:
You are trying to change the value of curr_length with curr_length = len(str_) inside a function which looks for a local curr_length variable, and can't find it. It needs the line global curr_length to know that it's a global variable.
As far as why you're wondering as to why a dict object does not need global memoized line, you should read the answer to:
Global dictionaries don't need keyword global to modify them? or Why is the global keyword not required in this case?
EXPLANATION:
In Python, a variable declared outside of the function or in global scope is known as global variable. This means, global variable can be accessed inside or outside of the function.
Let's see an example on how a global variable is created in Python.
x = "global"
def foo():
print("x inside :", x)
foo()
print("x outside:", x)
When we run the code, the will output be:
x inside : global
x outside: global
In above code, we created x as a global variable and defined a foo() to print the global variable x. Finally, we call the foo() which will print the value of x.
What if you want to change value of x inside a function?
def foo():
x = x * 2
print(x)
foo()
When we run the code, the will output be:
UnboundLocalError: local variable 'x' referenced before assignment
The output shows an error because Python treats x as a local variable and x is also not defined inside foo().
To make this work we use global keyword
I am learning Python on my own and I am baffled on what is wrong in the following code
glob_var = 0
def print_glob_var():
s = 0
while glob_var > 0:
s = s+1
glob_var = glob_var - 1
return s
#print (globvar)
def main():
global glob_var
glob_var = 4
print_glob_var()
main()
I am getting error "UnboundLocalError: local variable 'glob_var' referenced before assignment" . However when I use only the print the code block works fine.
What I am doing wrong. I am using Python 3.5.2
In order to change the value of a global variable inside a function, you must declare it global inside the function. You seem to do so in function main, but not in function print_glob_var.
Python analyses the body of print_glob_var, sees an assignment to glob_var (specifically glob_var = glob_var - 1) and no global statement, and decides based on that that glob_var is a local variable that it expects to see defined within the function. If you remove the assignment you will no longer get this error, although of course that creates new problems. Alternatively you could add global glob_var to the function. Including it in main is not enough, you need that statement everywhere the variable is used.
This is the kind of reason that using non-constant global variables in Python is a bad idea. Learn about classes.
glob_var = 4
def print_glob_var():
global glob_var # Set glob_var as global
s = 0
while glob_var > 0:
s = s+1 # You can do s += 1 here
glob_var = glob_var - 1
print(glob_var) # Your commented out print() was after the return statement
return s # so it would never be reached.
def main():
print_glob_var()
main()