Skip navigation

UnboundLocalError: local variable referenced before assignment

So that sucks

Howdya fix that?

I’ll tell you. First, a simple example of the problem:

#This is valid python 2.5 code
#My global variable:
USER_COUNT = 0


#functions:
def Main():    
  AddUser()

def AddUser():
  print 'There are',USER_COUNT,'users so far'


# actually run Main()
Main()

^ That program WORKS FINE. Function AddUser() just references the USER_COUNT variable, which was declared as a global (outside of any of the function blocks).

Here’s where it goes wrong: when we try to write to or we try to update the value of the global variable

#USER_COUNT is a GLOBAL variable
USER_COUNT = 0


def Main():    
  AddUser()

def AddUser():
  USER_COUNT = USER_COUNT + 1
  print 'There are',USER_COUNT,'users so far'
  

Main()

Then we get: UnboundLocalError: local variable ‘USER_COUNT’ referenced before assignment

So that sucks.

The reason this happens is because AS SOON AS YOU WRITE TO A VARIABLE, that variable is AUTOMATICALLY considered LOCAL to the function block in which its declared. Namely:

#USER_COUNT is a GLOBAL!
USER_COUNT = 0

def AddUser():
  USER_COUNT = USER_COUNT + 1
  print 'There are',USER_COUNT,'users so far'

EVEN THOUGH we declared USER_COUNT as a GLOBAL, the simple act of WRITING TO IT __ANYWHERE__ in the function scuzzles-up the “globalness” of the USER_COUNT variable, and like, automatically makes ANY use of USER_COUNT refer to a LOCAL VARIABLE inside of AddUser().

So howdya fix it?

Easy! You do this:

#global
USER_COUNT = 0

def Main():    
  AddUser()

def AddUser():
  global USER_COUNT ######!!! IMPORTANT !!!  Make sure
  # to use the GLOBAL version of USER_COUNT, not some
  # locally defined copy of that.  I think this
  # might be a python feature to stop functions from
  # clobbering the global variables in a program
  USER_COUNT = USER_COUNT + 1
  print 'There are',USER_COUNT,'users so far'
  
  

Main()

This is an ok-nice feature that might stop a program’s functions from clobbering the globals (since you really have this “just use it” attitude to a variable and you may have no clue that you’re clobbering a global), but really it might be nice if python were more consistent and required use of this global thing for BOTH read/write. Though I guess it could be kinda convenient behavior .. I don’t know yet, haven’t programmed in python for long enough.

About these ads

54 Comments

  1. Addendum: Looks like I am not the only person who this surprises.

    …before the “if” statement… but I don’t understand why. Is the
    > interpreter scanning my entire function definition before executing
    > it, recognizing that I *might* assign COLUMNS to a value, and deciding
    > that it’s a local on that basis?

    You name it. That’s *exactly* what happens.

    • Anonymous
    • Posted April 3, 2009 at 10:38 pm
    • Permalink

    This was a very helpful explanation for the precise problem I was having. Thanks!

    • Anonymous
    • Posted April 9, 2009 at 9:25 pm
    • Permalink

    This solved my problem. Thanks!

    • AKMapGirl
    • Posted June 23, 2009 at 8:32 pm
    • Permalink

    Thank you so much for posting this!! Exactly the issue I was facing; now on to the next one! :)

  2. Wow! You saved my life – thanks!

    • yossale
    • Posted March 8, 2010 at 11:59 am
    • Permalink

    Cool , thanks :)

  3. I would’ve never found it.

    Thank you so much!!

    • phaliure
    • Posted March 29, 2010 at 11:39 pm
    • Permalink

    Very helpful, thanks for the post. Fianlly solved the issue I was having.

    • squid
    • Posted April 13, 2010 at 3:12 am
    • Permalink

    Very helpful! This saved me from making an ugly workaround. Thanks very much.

    • Senyai
    • Posted May 17, 2010 at 11:33 am
    • Permalink

    Does not work in my case (python 2.5):

    class A(object):
    def __init__(self):
    s = ‘hello’
    def test():
    s+=’, world!’
    test()
    A()
    I know, I should use StringIO.

    • kls
    • Posted June 29, 2010 at 10:33 am
    • Permalink

    awesum…

  4. totally liked it :)

    • AA
    • Posted July 14, 2010 at 10:48 pm
    • Permalink

    Excellent explanation!!

    • xanaguy
    • Posted July 26, 2010 at 6:28 pm
    • Permalink

    Silly Python. Thanks for the clear explanation!

    • molly
    • Posted September 7, 2010 at 7:32 pm
    • Permalink

    Thanks! You’re a good explainer!

    • jonny
    • Posted October 4, 2010 at 6:12 am
    • Permalink

    … who would have thought?

    • shreyans jain
    • Posted November 27, 2010 at 7:02 am
    • Permalink

    Thanks tons :) Works perfectly :))

    • Ramiro
    • Posted December 6, 2010 at 6:18 pm
    • Permalink

    The error i gets is :
    Traceback (most recent call last):
    File “C:\HomePy\Amsa\src\Listos\Folele.py”, line 75, in onAction
    self.OnCuenta(None)
    File “C:\HomePy\Amsa\src\Listos\Folele.py”, line 127, in OnCuenta
    con = con + 1
    UnboundLocalError: local variable ‘con’ referenced before assignment

    • vijay
    • Posted December 13, 2010 at 6:29 pm
    • Permalink

    cool man!! Thanks.. It solved my problem…

    • DP
    • Posted January 10, 2011 at 6:19 pm
    • Permalink

    Thnx a lot…. it worked perfectly…… :)

    • Daren Scot Wilson
    • Posted January 28, 2011 at 6:37 pm
    • Permalink

    A clear and useful explanation. Thanks! I wasted several minutes being puzzled. This page was the first one that came up when I googled “local variable” and “referenced before assignment”, and has solved my Python programming problem immediately.

    • srinivas
    • Posted February 2, 2011 at 12:52 pm
    • Permalink

    thanks a lot this explanation is very useful to every one who are wking in python language

    • David Ravnsborg
    • Posted April 18, 2011 at 11:43 am
    • Permalink

    Thank you – this is the clearest description of the issue I have come across.

    I just set up a Jython interpreter in a Java project and I was getting this error in my Python test script. I was having a hard time figuring out what the error stemmed from, though I was able to narrow it down to the fact that it occurred only when I modified a variable within the scope of a function.

    • Abhishek Sharma
    • Posted June 1, 2011 at 9:10 pm
    • Permalink

    Wow, I had a really specific error and thought I wouldn’t find it. Thanks for helping me finish my assignment on time!

    • Alex
    • Posted June 28, 2011 at 11:32 am
    • Permalink

    Wow thats not obvious behavior. Thanks for clearing that up. :)

    • Anonymous
    • Posted July 1, 2011 at 10:04 am
    • Permalink

    Note that Javascript has the same semantics on such scenario.

  5. @Anonymous Yes, JavaScript has the problem of “global variable clobbering”, since you are not required to declare “global varName” at the start of a function that writes a global.

    • Anonymous
    • Posted September 21, 2011 at 4:20 pm
    • Permalink

    Nice ! It worked. I looked for this answer a long time.

  6. Thanks! That helped!

  7. pretty awesome, thanks for the help

    • Julie
    • Posted October 11, 2011 at 9:51 am
    • Permalink

    Yet another thankful python user!

    • Anonymous
    • Posted October 28, 2011 at 4:10 pm
    • Permalink

    Informative. Thank you.

    • rahul
    • Posted November 10, 2011 at 2:56 pm
    • Permalink

    really…u r genius…

  8. Worked like a charm!

    Thank you :)

    • aaaaa
    • Posted November 10, 2011 at 10:21 pm
    • Permalink

    Thanks mate. I’m really grateful to you!

    • Anonymous
    • Posted December 14, 2011 at 12:48 pm
    • Permalink

    This solved my problem. Thanks!

  9. It works, thanks! I’ve fixed it :)

    • Anonymous
    • Posted January 7, 2012 at 11:29 am
    • Permalink

    Thank you !!!! :))

    • sahaninoo
    • Posted February 10, 2012 at 11:05 am
    • Permalink

    thunks man !

    • Python Progyo
    • Posted February 22, 2012 at 12:09 pm
    • Permalink

    Thanks. : )

    • Bubba
    • Posted February 23, 2012 at 5:35 pm
    • Permalink

    Which is why globals are evil and you should never ever use them!

    • Anonymous
    • Posted March 2, 2012 at 3:49 am
    • Permalink

    Thanks very helpful!!

    • DjTrilogic
    • Posted March 28, 2012 at 11:19 pm
    • Permalink

    Helpful Thank you !

  10. My thanks goes out to you. This is by far the best description for the given error message.

  11. Thank you! Exactly the answer I was Google-ing for. Good presentation too, didn’t have to re-read anything.

    • Anonymous
    • Posted May 8, 2012 at 9:12 am
    • Permalink

    Thank you SOOOO much, luv u man <3
    My computers teacher is so crap and doesn't know anything haha
    Helped me out heaps churr

    • Jawad
    • Posted May 26, 2012 at 7:25 pm
    • Permalink

    Bless you! Had one of those of moments that can lead to hating a programming language!

    • Anonymous
    • Posted May 28, 2012 at 1:01 pm
    • Permalink

    I’ll add to the list: thank you!

    • Anonymous
    • Posted October 19, 2012 at 1:18 am
    • Permalink

    Thank you very much!! =)

    • Anonymous
    • Posted January 28, 2013 at 2:17 am
    • Permalink

    THANK YOU THANK YOU THANK YOU PLEASE LEAVE THIS UP FOREVER

  12. @Anonymous Will do.

    • Wm
    • Posted March 10, 2013 at 11:38 pm
    • Permalink

    Like everyone else, just what I needed. The problem with this is that no other programming language I have ever used does this. Global MEANS global and it should mean global in Python also.

    • Anonymous
    • Posted March 13, 2013 at 3:27 pm
    • Permalink

    Great! Thanks

  13. I was wondering if you ever considered changing the structure
    of your blog? Its very well written; I love what youve got to say.
    But maybe you could a little more in the way of content so people could
    connect with it better. Youve got an awful lot of
    text for only having 1 or two pictures. Maybe you could space it out better?


One Trackback/Pingback

  1. By Créer un jeu du pendu en Python 2.7 | Yann P. on 16 Jan 2013 at 4:44 pm

    [...] Et ensuite ? On regarde si résultat est vide. Si il l’est, on lui fera perdre une vie avec la très simple fonction qui suit. (j’ai mis global parce qu’il prenait la variable chances pour une variable locale, n’y faites pas attention mais ajoutez le bien, plus d’infos ici) [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 37 other followers

%d bloggers like this: