Global and Local Variables in Python
I am learning Python. The Python 3 book says the following code should work fine:
def funky():
print(myvar)
myvar = 20
print(myvar)
myvar = 10
funky()
But when I run it in Python 3.3 I got
UnboundLocalError: local variable 'myvar' referenced before assignment
mistake. I understand that the first print(myvar)
in funky
should be 10, since it is a global variable. The second print(myvar)
should be 20 since local myvar
is defined as 20. What's going on here? Please help clarify.
source to share
You need to call global
your function before assigning a value.
def funky():
global myvar
print(myvar)
myvar = 20
print(myvar)
myvar = 10
funky()
Note that you can print the value without calling the global, because you can access globals without using it global
, but you will need it to assign it.
source to share
From the docs :
Each occurrence of a name in a program text refers to a binding that is the name set in the innermost function block containing the use.
This means that if you don't declare it global
or nonlocal
(nested functions) then it myvar
is a local variable or free variable (if myvar
not defined in a function).
The book is wrong. Within the same block, the name represents the same variable (local variable myvar
in your example, you cannot use it until you define it, even if there is a global variable with the same name). Also you can change values ββoutside of the function, i.e. the text at the end of page 65 is also incorrect . The following works:
def funky(): # local
myvar = 20
print(myvar) # -> 20
myvar = 10 # global and/or local (outside funky())
funky()
print(myvar) # -> 10 (note: the same)
def funky(): # global
global myvar
print(myvar) # -> 10
myvar = 20
myvar = 10
funky()
print(myvar) # -> 20 (note: changed)
def funky(): # free (global if funky is not nested inside an outer function)
print(myvar) # -> 10
myvar = 10
funky()
def outer():
def funky(): # nonlocal
nonlocal myvar
print(myvar) # -> 5
myvar = 20
myvar = 5 # local
funky()
print(myvar) # -> 20 (note: changed)
outer()
source to share
Python "assumes" that we want to get a local variable because of the assignment of myvar inside funky (), so the first print statement throws ## UnboundLocalError: the local variable myvar that is referenced before the ## error message. Any variable that is changed or created within a function is local unless it has been declared a global variable. To tell Python that we want to use a global variable, we must use the global keyword, as shown in the following example:
def f():
global s
print s
s = "That clear."
print s
s = "Python is great!"
f()
print s
source to share