5

I am learning Python. A book on Python 3 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 the

UnboundLocalError: local variable 'myvar' referenced before assignment

error. My understanding is that the first print(myvar) in funky should be 10 since it's a global variable. The second print(myvar) should be 20 since a local myvar is defined to be 20. What is going on here? Please help clarify.

6
  • possible duplicate of local var referenced before assignment Commented Jan 20, 2013 at 4:48
  • 2
    While the duplicate answers your question, the simplest answer is that you can add global myvar at the start of the function if you want to treat it as a global variable. If you ever assign to myvar in the function (as you do in the line myvar = 20), Python assumes it is a local variable and thinks you are referring to it before it is defined. Commented Jan 20, 2013 at 4:50
  • @DavidRobinson Is this global new in Python 3.3 since that book didn't mention it? Commented Jan 20, 2013 at 4:58
  • 1
    No, global has been around for a while. Are you sure that the book wasn't giving this as an example of code that didn't work? Commented Jan 20, 2013 at 4:59
  • @DavidRobinson No. The book is at here. The bottom of page 66. Commented Jan 20, 2013 at 5:06

3 Answers 3

8

You need to call global in 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 global because you can access global variables without using global, but attempting to assign a value will require it.

Sign up to request clarification or add additional context in comments.

Comments

4

From the docs:

Each occurrence of a name in the program text refers to the binding of that name established in the innermost function block containing the use.

It means that unless you declare it global or nonlocal (nested functions) then myvar is a local variable or a free variable (if myvar is not defined in the function).

The book is incorrect. Within the same block the name represents the same variable (local variable myvar in your example, you can't use it until you define it even if there is a global variable with the same name). Also you can change values outside a 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()

Comments

0

Python "assumes" that we want a local variable due to the assignment to myvar inside of funky(), so the first print statement throws ## UnboundLocalError: local variable 'myvar' referenced before assignment ## error message. Any variable which is changed or created inside of a function is local, if it hasn't been declared as a global variable. To tell Python, that we want to use the global variable, we have to use the keyword "global", as can be seen in the following example:

def f():
  global s
  print s
  s = "That's clear."
  print s 


s = "Python is great!" 
f()
print s

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.