I have tried to search this but I don't quite understand. I am coming across this error so I formed a quick easy example.
def test():
global a
a = 0
a+=1
def test2():
a+=1
print (a)
inp = input('a?')
if inp == 'a':
test()
test2()
When I input a. I expected the code to output 2. However, I get this error UnboundLocalError: local variable 'a' referenced before assignment. When I searched around about this, I found that you need to use global, but I already am using it.
So I don't understand. Can someone briefly explain what I'm doing wrong?
Thanks.
A global declaration only applies within that function. So the declaration in test() means that uses of the variable a in that function will refer to the global variable. It doesn't have any effect on other functions, so if test2 also wants to access the global variable, you need the same declaration there as well.
def test2():
global a
a += 1
print(a)
1) You can return the modified value like:
def test():
a = 0
a+=1
return a
def test2(a):
a+=1
print (a)
inp = input('a?')
if inp == 'a':
a = test()
test2(a)
2) Or you can use a class:
class TestClass:
a = 0
def test(self):
self.a = 0
self.a+=1
def test2(self):
self.a+=1
print (self.a)
Usage of option 2:
>>> example = TestClass()
>>> example.test()
>>> example.test2()
2
Related
I have declared global variable in function a
def a():
global my_var
my_var = 3
If I want to read this variable from function main, everything works
if __name__ == "__main__":
main()
def main():
print(my_var)
Output:
3
However I have another function b, where the var is not defined
def b():
try:
random_numbers = (random.sample(range(1, my_var), 2))
except Exception as e:
print(e)
Output:
NameError: name 'my_var' is not defined
Could someone explain me, why in function main I can access my_var, while in another it is not defined? How can I solve this problem?
I'm writing a program in selenium python. I pasted here part of the code from my program (I did not paste all the code because it has 800 lines) with the UnboundLocalError error: local variable 'i' referenced before assignment, the error occurs exactly at i += 1.
global i
i = 0
odpowiadanieobserwowaniestronfb0()
def odpowiadanieobserwowaniestronfb0():
if i > ileraz:
driver.quit
skonczono()
'''
try:
testt = driver.find_element_by_xpath('')
except Exception:
odpowiadanieobserwowaniestronfb1()
zleskonczono1()
'''
def odpowiadanieobserwowaniestronfb1():
i += 1
global keyword tells the function, not the whole module / file, what variables should be considered declared outside the scope of the said function. Try this:
def odpowiadanieobserwowaniestronfb1():
global i
i += 1
There are two options:
You can use your global variable:
def odpowiadanieobserwowaniestronfb1():
global i
i += 1
or you pass the i to the function:
def odpowiadanieobserwowaniestronfb1( i ):
return i += 1
So what I'm trying to do is I need to assign a variable to use in several functions. But that variable should not be a global variable. How can I do that if it is possible?
Edit: I did forgot one thing. This is for my project and most of it is finished but this. My code needs to be non-repeated as much as it can. I have 5 variables and 15 functions to use some or all of that variables.
Edit2: Let me just post a function here.
def draw_stairs(top_stair_wide, stair_height, stair_count, character):
for o in range(stair_count):
for b in range(stair_height):
draw_straight_line(top_stair_wide, character)
print("")
top_stair_wide += 3
What I need to do is when I use that function, I need to fill "top_stair_wide", "stair_height", "stair_count" with a variable that is not global. I can't just put numbers because I will use those variables in 14 different functions again with maths.
I have a function that draws straight line and before, it inputs and returns character so those are not the problem.
Create a class, make the variables instance variables and turn the functions into methods. Then you can access the instance variables in each method without the explicit need to pass them around.
class C:
def __init__(self, var1, var2, var3):
self.var1 = var1
self.var2 = var2
self.var3 = var3
def add_them(self):
return self.var1 + self.var2 + self.var3
def multiply_them(self):
return self.var1 * self.var2 * self.var3
And so on.
You need parameter(s) in your function definition and then pass your variable(s) as argument(s) when you call it.
Using a main function as you told me in a comment, you could write it like this:
def main():
# Here are your NOT GLOBAL variables:
top_stair_wide = 1
stair_height = 2
stair_count = 3
character = "O"
def draw_stairs(top_stair_wide, stair_height, stair_count, character):
for o in range(stair_count):
for b in range(stair_height):
draw_straight_line(top_stair_wide, character)
print("")
top_stair_wide += 3
# ... more definitions follow
# Then call the functions...
# Job done when you execute the program:
main()
Alternatively:
def main(top_stair_wide, stair_height, stair_count, character): # <-- cram all the expected arguments there
def draw_stairs(top_stair_wide, stair_height, stair_count, character):
for o in range(stair_count):
for b in range(stair_height):
draw_straight_line(top_stair_wide, character)
print("")
top_stair_wide += 3
# ... more definitions follow
# Then call the functions...
# Job done when you execute the program:
main(1, 2, 3, "O")
It's also possible using kwargs, because then you have to know the arguments when you call main() and not when you define it:
def main(**kwargs):
def draw_stairs(**kwargs):
for o in range(kwargs["stair_count"]):
for b in range(kwargs["stair_height"]):
draw_straight_line(kwargs["top_stair_wide"], kwargs["character"])
print("")
kwargs["top_stair_wide"] += 3
# ... more definitions follow
# Then call the functions...
function1(**kwargs)
function2(**kwargs)
function3(**kwargs)
# Job done when you execute the program:
main(top_stair_wide = 1,
stair_height = 2,
stair_count = 3,
character = "O")
You can pass it to your functions like:
def func1(variable):
# your logic here with variable
return 'something'
def func2(variable):
# your logic here with variable
return 'something'
Or you can set it as constant in current file as:
VARIABLE = 'variable'
def func1():
# your logic here with VARIABLE
return 'something'
def func2():
# your logic here with VARIABLE
return 'something'
Another option is using a dictionary storing the shared parameters and only passing this dictionary (rather than all variables separately) as an argument:
def add_params(params):
return params['var1'] + params['var2'] + params['var3']
def multiply_params(params):
return params['var1'] * params['var2'] * params['var3']
>>> params = {'var1': 1, 'var2', 2, 'var3': 3}
>>> add_params(params)
6
>>> multiply_params(params)
6
I am learning python and have one question about how to save a dictionary value via a python function.
import copy
def func():
b = {'1':'d'}
a = copy.deepcopy(b)
global a
a = {}
func()
print a
The printout is still {}, how to make it be {'1':'d'}?
You need to say that you are accessing the global variable a, inside the function, like this
def func():
global a
b = {'1': 'd'}
a = copy.deepcopy(b)
But, prefer not doing something like that. Instead, return the copy and then store it in the calling place, like this
import copy
a = {}
def func():
b = {'1': 'd'}
return copy.deepcopy(b)
a = func()
print a
i moved the global a into the function definition.
#! /usr/bin/python
import copy
def func():
global a
b = {'1':'d'}
a = copy.deepcopy(b)
a = {}
func()
print a
You are defining 'a' in two different scopes, one in the "global" scope, one in the function scope. You will need to return copy.deepcopy(b) and set that to the value of the outer defined 'a'.
import copy
def func():
b = {'1':'d'}
return copy.deepcopy(b)
global a
a = func()
print a
Why does the first function 'define_vartest' not return the var as expected. Not until I make it global (the second function 'define_vartest_global'), does it work. And what is the difference between returning a var at the end of a function and defining a global var within same function??? I am puzzled.
def define_vartest():
vartest = 1
return vartest
def define_vartest_global():
global vartest_global
vartest_global = 1
return vartest_global
define_vartest()
define_vartest_global()
#print('vartest', vartest)
print('vartest_global', vartest_global)
Basically - if I remove the rem from the print vartest line the script stops. Why does the var not get defined, as I return it from the function?
Please explain
Answered below.
This code works as expected. Thanks
def define_vartest():
vartest = 1
return vartest
def define_vartest_global():
global vartest_global
vartest_global = 1
return vartest_global
vartest = define_vartest()
vartest_global = define_vartest_global()
print('vartest', vartest)
print('vartest_global', vartest_global)
You must assign the value you return:
def define_vartest():
vartest = 1
return vartest
vartest = define_vartest()
print('vartest', vartest)
Otherwise the print statement will be unable to see it, because they are in different scope.
This mean that vartest inside the function and vartest outside are different variables. With the return you give the value of the vartest inside to the vartest outside.
Because you never read the returned value. Think about this:
def foo():
return 1
foo()
What is going to happen with the 1? It's lost since no one cares. You need to save it in a new variable to keep it:
def foo():
return 1
vartest = foo()
Now let's add a local variable:
def foo():
a = 1
return a
b = foo() # assign the result of the function call to "b"
# "a" is undefined since it's local to "foo"
print('b',b)
This effect is called "scoping". Each variable has a "scope", a kind of horizon within which it is visible. It's not visible outside. That way, you can reuse names in different functions.