I want to have a global variable changed form inside a function. The global variable is an integer. I am getting an error when trying to do so. This is a simplified version of what I am trying to do:
variable = 3
def test():
b = 5
if b > 0:
variable -= 1
print(variable)
else:
print('fail')
test()
Can anyone help me in finding a way to reduce the integer variable by 1 every time the function test runs?
When referring to a variable that's outside of a function that you don't pass in as a parameter, you must declare it as global before referencing it. Add global variable to the beginning of your function and it should work.
variable = 3
def test():
b = 5
global variable
variable -= 1
if b > 0:
print(variable)
else:
print('fail')
test()
test()
test()
test()
test()
test()
output:
2
1
0
-1
-2
-3
Note that the condition will not satisfy to fail because we are not doing anything with b that is equals to 5 forever.
Related
I am trying to understand local/global/nonlocal capture rules for python scoping and have encountered some asymmetric behavior, here is an example:
def test():
i = 0
d = dict()
def next():
d[len(d)] = 'foo' # why is nonlocal d not required?
nonlocal i # Required to pull 'i' into next.locals()
i += 1
while i < 10:
next()
test()
From the above snippet we have variables d and i declared and defined as dict and int types respectively. However in the nested function next only d can be reached, i requires the nonlocal term to pull i into the function's scope.
I next theorized that non-referenceable types in python get lifted into the context of it's children's scope.
However this next example contradicts my theory:
def test2():
def If():
return True if qn == None else qn
def Ask():
nonlocal qn
qn = i < lim
return If()
qn = None
i = 0
lim = 5
while i < 10:
i += 1
print(i, Ask())
Notice that in test2's Ask function I do not need to declare nonlocal i and nonlocal lim but require nonlocal qn.
Is this behavior expected? I would assume either both should require nonlocal or neither would require it.
Is there a language specification I can reference for similar types of behavior?
For better understanding here is a example code.
num = 0
def func(num):
num += 1
func(num)
print(num)
This code prints 0 but I want 1(incremented by func()), how can I do that?
How can I do that? Is it possible?
Long story short, you can't just put number in function and expect it to be passed by reference.
In python...
(act like) pass by value : whole numbers, strings or tuples
(act like) pass by reference : python list
You should visit here for more info about "Pass(call) by Object Reference".
https://www.geeksforgeeks.org/is-python-call-by-reference-or-call-by-value/
In python, when you declare a variable inside a function, python treats it as a new variable. That means, any changes to that variable doesnt show up Globally.
To go through his, add global to the top.
Example:
num = 0
def func():
global num
num += 1
func()
print(num)
Output:
1
def change(a):
a=4
print('1:')
c=3
print('Value before changing',c)
change(c)
print('Value after changing',c)
print('2:')
d=6
print('Value before changing',d)
change(d)
print('Value after changing',d)
print('3:')
e=7
print('Value before changing',e)
change(e)
print('Value after changing',e)
I want to change n distinct global variables. Eg: I want to change c,d and e global variables using function by passing it as a argument. How can I do so?
Edit:
My original answer wouldn't have worked. So here's my new answer. First, you'll need a function to get the name of the variable. This can be done with the builtin inspect package like so,
import inspect
def retrieve_name(var):
callers_local_vars = inspect.currentframe().f_back.f_locals.items()
return [var_name for var_name, var_val in callers_local_vars if var_val is var]
Then, you'll need to rewrite your change function to
def change(a):
globals()[a] = 4
And use it in conjunction with the retrieve_name function like so,
change(retrieve_name(x)[0])
Because if you just put the retrieve_name inside change it will always return a.
Below is my original answer:
Tell the function change that a is global. Eg:
def change(a):
global a
a = 4
the global keyword tells the function that there already exists a variable of this name, defined outside the current scope. It is in, what python calls, the global scope (think the outter-most scope of a python file).
>>> def change(a, value=4):
global a
a = value
>>> x = 3
>>> change(x)
# x = 4
I've updated my previous answer so that it should work, but here is an alternative method.
def change(**kwargs):
for name in kwargs:
globals()[name] = 4
x = 3
change(x=x) # whatever follows the '=' sign is redundant in this case
Or, you could do
def change(**kwargs):
globals().update(kwargs)
x = 3
change(x=4) # the global value of 'x' is now 4
I'm trying to write a simple code that uses a global variable. I'm getting the following error
UnboundLocalError: local variable 'x' referenced before assignment
global x
def update():
x = x + 1
x = 0
update()
print(x)
Your error occurred because in the function update, you are trying to edit a variable (x) that is not defined, at least not locally.
The global keyword should be inside the function, and hence tell that the x you are speaking about is the one defined outside of the function (therefore globally defined) :
def update():
global x
x = x + 1
x = 0
update()
print(x)
This would output 1, as expected.
You can take a look at this well detailed answer regarding the use of the global keyword.
im trying to print the next item in the list by using this function I defined below :
List = [1,2,3,4,5]
def next():
i=0
if (i<4):
i= i + 1
print (List[i])
The output of this remains as the second index and doesn't increments no matter how many times i call it
Thanks.
i in the next function is a local variable. It is always initialized to 0 when the function is called.
To make the variable i remember the last value, make it as a global variable.
i = 0 # <--- global variable
def next():
global i # <--- declare `i` as a global variable
if (i<4):
i= i + 1
print (List[i])