UnboundLocalError - (code is short & simple)

Chris Kaynor ckaynor at zindagigames.com
Mon Sep 28 12:00:18 EDT 2009


On Sun, Sep 27, 2009 at 10:39 PM, New User <for_python at yahoo.com> wrote:

> Hi Chris,
>
> Thank you for the reply and info!
>
> Re:  "from coin_toss import coin_toss"
>
> My understanding is that this line makes the coin_toss() function in the
> coin_toss.py file available to the toss_winner() function.  Is that what
> your explanation on this point meant (i.e. "... and sets the
> local variable coin_toss to the value of coin_toss in the module coin_toss
> ")?
>

That is the effect of the statement, however there are cases when the from
coin_toss import coin_toss may result in a different value in the module.
This is because:
from coin_toss import coin_toss
effectively does:
import coin_toss
coin_toss = coin_toss.coin_toss


While this normally works as intended, it can have some unexpected effects.
Take, for example:

-----ALPHA.PY-----
from gamma import test
import beta
import gamma

test = 2
gamma.test = 3
print gamma.test
print test
print beta.test
print beta.gamma.test

-----BETA.PY----
from gamma import test
import gamma


----GAMMA.PY-------
test = 1




With this setup, you'll get the output:
>>> import Test.alpha
3
2
1
3



If, however, you change gamma to read:
test = ['1']



and the lines in alpha:

test = 2
gamma.test = 3

to read:

test.append('2')
gamma.test.append('3')

you'll get:
>>> import Test.alpha
['1', '2', '3']
['1', '2', '3']
['1', '2', '3']
['1', '2', '3']



As this shows, the "from MODULE import VALUE" method rebinds the varible
from another module in the local scope, and thus does:
import MODULE
VALUE = MODULE.VALUE
del MODULE


This means that for some types, the value in MODULE and the value in the
local scope may not be the same and other times they may be the same.


For your purposes, you'll notice no real difference. However this is
something to keep in mind.




>
> Re:  "... within a function, a different namespace exists ....", and "... you
> may want to look into the global keyword ....."
>
> Ok, I will read up on these.  Thank you for the tips!
>
> Martin
>
> P..S.  I didn't see your reply to my post in the comp.lang.python Google
> Groups.  I assume you emailed your reply directly to me.  I also assume
> you're not looking for my response in comp.lang.python Google Groups.  This
> is my first time posting, so I'm not sure what the "posting-reply"
> conventions are.
>

 It should have shown up on the python list - I just forgot to remove you
from it (I used G-Mail's reply all). In general, unless the reply is
off-topic or personal, it should be replied to on-list. This allows more
people to both see the answer and to help further explain the answer.


>
> --- On *Mon, 9/28/09, Chris Kaynor <ckaynor at zindagigames.com>* wrote:
>
>
> From: Chris Kaynor <ckaynor at zindagigames..com>
> Subject: Re: UnboundLocalError - (code is short & simple)
> To: "pylearner" <for_python at yahoo.com>
> Cc: python-list at python.org
> Date: Monday, September 28, 2009, 4:17 AM
>
>
> Lets look at what is happening on a few of the lines here:
>
> First:
> from coin_toss import coin_toss
>
> imports the module coin_toss and sets the local variable coin_toss to the
> value of coin_toss in the module coin_toss.
>
>
> Second:
> coin_toss = coin_toss()
>
> calls the function bound to the name coin_toss and assigns the result to
> coin_toss. Now this appears to be what you want (and run outside a function
> it would work as you intend, the first time). However, within a function, a
> different namespace exists, and Python sees that you are assigning to
> coin_toss, and thus uses the local version of that variable everywhere else
> within the function. As such, Python is attempting to call the
> local variable coin_toss, which has not yet been assigned too.
>
>
>
> While not really the "correct" solution, you may want to look into the
> global keyword for more information about your problem.
>
>
>
> Chris
>
>
> On Sun, Sep 27, 2009 at 8:53 PM, pylearner <for_python at yahoo.com<http://mc/compose?to=for_python@yahoo.com>
> > wrote:
>
>> Python version = 2.6.1
>> IDLE
>> Computer = Win-XP, SP2 (current with all windows updates)
>>
>> ---------------------------------------------------------------
>>
>> Greetings:
>>
>> I have written code for two things:  1) simulate a coin toss, and 2)
>> assign the toss result to a winner.  Code for the simulated coin toss
>> is in a file named "coin_toss.py."  Code for the assignment of the
>> toss result is in a file named "toss_winner.py."  Each file has one
>> simple function:  1) coin_toss(), and 2) toss_winner(), respectively.
>> The code for each file is listed below.
>>
>> Problem:
>>
>> I am getting an error when I run "toss_winner.py."  The error message
>> is listed below.
>>
>> Question #1:
>>
>> Why am I getting this error?
>>
>> Explanation:
>>
>> As I understand it, the first statement of the toss_winner() function
>> body -- i.e. "coin_toss = coin_toss()" -- causes four things to
>> happen: 1) the coin_toss() function is called, 2) the coin_toss()
>> function is executed, 3) the coin_toss() function returns the value of
>> its local "coin_toss" variable, and 4) the returned value of the "coin
>> toss" variable that is local to the coin_toss() function is assigned
>> to the "coin toss" variable that is local to the toss_winner()
>> function.
>>
>> Given this understanding, it seems I should NOT be getting a
>> "referenced before assignment" error, involving the "coin_toss" local
>> variable of "toss_winner()."
>>
>> Note:
>>
>> I am new to programming and Python.  I'm currently self-studying
>> "Python Programming: An Intro to Computer Science" by Zelle.
>>
>> Thanks!
>>
>> -------------------------------------------------------------------
>>
>> Traceback (most recent call last):
>>  File "<pyshell#2>", line 1, in <module>
>>    toss_winner()
>>  File "C:/Python26/toss_winner.py", line 7, in toss_winner
>>    coin_toss = coin_toss()
>> UnboundLocalError: local variable 'coin_toss' referenced before
>> assignment
>>
>> ---------------------------------------------------------------
>>
>> # toss_winner.py
>>
>> from coin_toss import coin_toss
>>
>> def toss_winner():
>>
>>    coin_toss = coin_toss()
>>
>>    if coin_toss == "Heads":
>>        toss_winner = "Player A"
>>        print 'From "toss_winner" function >>',
>>        print "Toss Winner = " + str(toss_winner)
>>
>>    else:
>>        toss_winner = "Player B"
>>        print 'From "toss_winner" function >>',
>>        print "Toss Winner = " + str(toss_winner)
>>
>>    return toss_winner
>>
>> ---------------------------------------------------------------
>>
>> # coin_toss.py
>>
>> from random import random
>>
>> def coin_toss():
>>
>>    random_number = random()
>>
>>    if random_number < .5:
>>
>>        coin_toss = "Heads"
>>
>>        print 'From "coin_toss" function >>',
>>        print "Toss result = " + str(coin_toss)
>>
>>    else:
>>
>>        coin_toss = "Tails"
>>
>>        print 'From "coin_toss" function >>',
>>        print "Toss result = " + str(coin_toss)
>>
>>    return coin_toss
>> --
>> http://mail.python.org/mailman/listinfo/python-list
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20090928/6bc1deac/attachment-0001.html>


More information about the Python-list mailing list