Global variables are special. If you try to assign to a variable a = value inside of a function, it creates a new local variable inside the function, even if there is a global variable with the same name. To instead access the global variable, add a global statement inside the function:
a = 7
def setA(value):
global a # declare a to be a global
a = value # this sets the global value of a
See also Naming and binding for a detailed explanation of Python's naming and binding rules.
Answer from Adam Rosenfield on Stack OverflowGlobal variables are special. If you try to assign to a variable a = value inside of a function, it creates a new local variable inside the function, even if there is a global variable with the same name. To instead access the global variable, add a global statement inside the function:
a = 7
def setA(value):
global a # declare a to be a global
a = value # this sets the global value of a
See also Naming and binding for a detailed explanation of Python's naming and binding rules.
The trick to understanding this is that when you assign to a variable, using =, you also declare it as a local variable. So instead of changing the value of the global variable a, setA(value) actually sets a local variable (which happens to be called a) to the value passed in.
This becomes more obvious if you try to print the value of a at the start of setA(value) like so:
def setA(value):
print "Before assignment, a is %d" % (a)
a = value
print "Inside setA, a is now %d" % (a)
If you try to run this Python will give you a helpful error:
Traceback (most recent call last):
File "scopeTest.py", line 14, in
setA(42)
File "scopeTest.py", line 7, in setA
print "Before assignment, a is %d" % (a)
UnboundLocalError: local variable 'a' referenced before assignment
This tells us that Python has decided that the setA(value) function has a local variable called a, which is what you alter when you assign to it in the function. If you don't assign to a in the function (as with printA()) then Python uses the global variable A.
To mark a variable as global you need to use the global keyword in Python, in the scope that you want to use the global variable. In this case that is within the setA(value) function. So the script becomes:
a = 7
def printA():
print "Value of a is %d" % (a)
def setA(value):
global a
a = value
print "Inside setA, a is now %d" %(a)
print "Before setA"
printA()
setA(42)
print "After setA"
printA()
This one line addition tells Python that when you use the variable a in the setA(value) function that you are talking about the global variable, not a local variable.
Why can't I set a global variable in Python? - Stack Overflow
Global variable is not recognised in a function
Why the global variable is not working in the different functions in Python? - Stack Overflow
Global variables not working in functions
Videos
You need the global statement:
def foo():
global G
if G is None:
G = 1
In Python, variables that you assign to become local variables by default. You need to use global to declare them as global variables. On the other hand, variables that you refer to but do not assign to do not automatically become local variables. These variables refer to the closest variable in an enclosing scope.
Python 3.x introduces the nonlocal statement which is analogous to global, but binds the variable to its nearest enclosing scope. For example:
def foo():
x = 5
def bar():
nonlocal x
x = x * 2
bar()
return x
This function returns 10 when called.
You need to declare G as global, but as for why: whenever you refer to a variable inside a function, if you set the variable anywhere in that function, Python assumes that it's a local variable. So if a local variable by that name doesn't exist at that point in the code, you'll get the UnboundLocalError. If you actually meant to refer to a global variable, as in your question, you need the global keyword to tell Python that's what you meant.
If you don't assign to the variable anywhere in the function, but only access its value, Python will use the global variable by that name if one exists. So you could do:
G = None
def foo():
if G is None:
print G
foo()
This code prints None and does not throw the UnboundLocalError.
Hi,
I have the following situation. I am building hangman game, so far it works well, I can get a random number from the list and start guessing letters. I have 7 tries because I have 7 stages of hanging in the stages list. For some reason I cannot get my counter to work, in order to count the amount of times I have the wrong letter and print the correct image (actually it prints the correct image, but even if my letter is right the counter adds one).
In the code I have marked the two places that I have problem with (<-------- This variable ------------). I have declared a global variable and in one of my functions I add 1 to it if the statement is True. For some reason this variable is not recognised as global. Any suggestions on how to overcome this problem?
I have some commented code in my last function, that also doesn't work as expected. If letter_guesses is used in the last function from the code it works but in the place_letter function it is not recognised.
import random
word_list = ["aardvark", "baboon", "camel"]
# Task 1 select a word from list
chosen_word = random.choice(word_list)
print(chosen_word)
hidden_word = []
for letter in chosen_word:
hidden_word.append("_")
stages = ['''
+---+
| |
O |
/|\ |
/ \ |
|
=========
''', '''
+---+
| |
O |
/|\ |
/ |
|
=========
''', '''
+---+
| |
O |
/|\ |
|
|
=========
''', '''
+---+
| |
O |
/| |
|
|
=========''', '''
+---+
| |
O |
| |
|
|
=========
''', '''
+---+
| |
O |
|
|
|
=========
''', '''
+---+
| |
|
|
|
|
=========
''']
def split_word(word):
return [char for char in word]
letter_guesses = 0 #<-------- This variable ------------
def place_letter():
letter_input = input("Guess a letter: ").lower()
checker = split_word(chosen_word)
for index, letter in enumerate(chosen_word):
if letter == letter_input:
hidden_word.pop(index)
hidden_word.insert(index, letter_input)
else:
pass
if letter_input not in checker:
letter_guesses += 1 #<-------- This variable ------------
print(stages[(len(stages) - 1) - letter_guesses])
while "_" in hidden_word or letter_guesses <= 7:
place_letter()
print(hidden_word)
# if letter_input not in split_word(chosen_word):
# letter_guesses += 1
if "_" not in hidden_word:
print("You won!")
break
if letter_guesses >= len(stages):
print("You lost.")
breakYou need the global definition in each function in which you use that variable.
def appnd():
global i
Note: If possible, move global variables and related functions into a class.
The next definition will work:
def appnd():
j=i
while i in range(i,j+3):
print "%s .Line..\n" %i
# it would print infinitely, but will work
At compile time Python looks at a way variables are used in the function to define a scope to look for them. In your definition of appnd it sees assign for i thus trying to threat it as local variable. In my code there are no assignments, so Python simply get the value for i from the parent scope - in this case i is neither local nor global, it called free variable. Execution model - Scopes and Binding - highly recommended reading.
In your case the variable you want to access is not global, it is in the scope of the class.
global_var = "global"
class Example:
class_var = "class"
def __init__(self):
self.instance_var = "instance"
def check(self):
print(instance_var) # error
print(self.instance_var) # works
print(class_var) # error
print(self.class_var) # works, lookup goes "up" to the class
print(global_var) # works
print(self.global_var) # works not
You only need the global keyword if you want to write to a global variable. Hint: Don't do that because global variables that are written to bring nothing but pain and despair. Only use global variables as (config) constants.
global_var = "global"
class Example:
def ex1(self):
global_var = "local" # creates a new local variable named "global_var"
def ex2(self):
global global_var
global_var = "local" # changes the global variable
Example().ex1()
print(global_var) # will still be "global"
Example().ex2()
print(global_var) # willnow be "local"
if you want to use variable in class, you can use self.xxx
class A:
... var = []
... def test(self):
... self.var.append(10)
... print self.var
Your issue is that functions create their own namespace, which means that done within the function is a different one than done in the second example. Use global done to use the first done instead of creating a new one.
def function():
global done
for loop:
code
if not comply:
done = True
An explanation of how to use global can be found here
done=False
def function():
global done
for loop:
code
if not comply:
done = True
you need to use the global keyword to let the interpreter know that you refer to the global variable done, otherwise it's going to create a different one who can only be read in the function.