UnboundLocalError

C

Camellia

hi all

why it generates an "UnboundLocalError" when I do the following:

<code>
....
def main():
number = number()
number_user = user_guess()
while number_user != number:
check_number(number = number, number_user = number_user)
number_user = user_guess()

UnboundLocalError: local variable 'number' referenced before assignment
</code>

I found when I changed the number() to num() or whatever the issue
solved
but doesn't every function has its own namespace?
Can anyone please explain it to me?

Peace
 
B

Benjamin Niemann

Hello,
why it generates an "UnboundLocalError" when I do the following:

<code>
...
def main():
number = number()
number_user = user_guess()
while number_user != number:
check_number(number = number, number_user = number_user)
number_user = user_guess()

UnboundLocalError: local variable 'number' referenced before assignment
</code>

I found when I changed the number() to num() or whatever the issue
solved
but doesn't every function has its own namespace?
Can anyone please explain it to me?

When Python compiles your code, it sees that you are using a local
variable 'number' in this function ('number = ...') and probably allocates
some memory for it or whatever - ask the core Python hackers for details.
When this statement is executed, the right hand side is evaluated first and
Python finds a reference to 'number'. It knows that number is a local
variable in main(), but has not been assigned yet (which would happend
after the right hand side is evaluated) - thus the error.

Even if you could get this to work, you have two 'number's in the function
with different meaning, which just makes understanding the code too
difficult.

Is number() (the global one) a function or class. I guess it's a function,
so I would suggest to name it 'get_number' (and same
for 'get_user_guess') - this makes the code more descriptive. Should it
really be a class, a common convention is to capitalize it 'Number()'.


HTH
 
T

Terry Reedy

Camellia said:
hi all

why it generates an "UnboundLocalError" when I do the following:

<code>
...

Presumably, the elided code includes a 'def number():' statement
def main():
number = number()

Within a function, a given name can be either global or local, but not
both.
Here you are expecting the compiler to interpret the first occurance of
'number' as local and the second as global. Humans can often resolve such
ambiguities correctly, but not necessarily always. So this is too much to
ask of a program and hence it is not allowed.

As Benjamin said, use two different names for the two different objects
that you need to use in the same context.

Terry Jan Reedy
 
R

Rob Williscroft

Terry Reedy wrote in
in
comp.lang.python:
Within a function, a given name can be either global or local, but not
both.
Here you are expecting the compiler to interpret the first occurance
of 'number' as local and the second as global. Humans can often
resolve such ambiguities correctly, but not necessarily always. So
this is too much to ask of a program and hence it is not allowed.

".. asked too much of the programme", sounds like a BOFH excuse to
me ;-).

Seriously I'd bet (if I were a gambling man) that this is by design,
not either of "too much work for the interpreter" or "nobody's
submitted a patch".

IOW: Why should the intepreter do more work just so the user
can find new and interesting ways to shoot them selves in the foot.

Rob.
 
C

Camellia

Thank you all so much for all the replies:)

But sorry I'm so dumb I can't say I really understand,
what do I actually do when I define a function with its name "number"?
why does a name of a function has something to do with a variable?

Oh wait can I do this in Python?:
<code>
def a():
def b()
</code>

so the b() will appear to be a local function which is the possible
cause of my little own error because the compiler will interpret the
number() as a local function but a global one?
 
G

Gabriel Genellina

But sorry I'm so dumb I can't say I really understand,
what do I actually do when I define a function with its name "number"?

Don't apologize, Python is a lot more dumb than you. It obeys very
simple rules (a good thing, so we can clearly understand them, once
we know them).
Recalling your previous example:

Python first scans the source code looking for assigned-to names.
That is, names to the left of equal signs. Those names, plus the
function formal parameters, make the list of "local names". Any other
names referenced are assumed to be globals, that is, living outside
your function. (That's not entirely true but enough for now).
Notice that "number" is a local name because it's assigned to; it
doesn't matter whether a global name "number" exists or not.
When the code is executed, the "number" to the right references the
local name, which has not been assigned to yet - that's why you get
an UnboundLocalError. "number" can't be a global name when used on
the right hand side, and a local name when used on the left hand
side. It's simple: it is local, or not, but not both.
why does a name of a function has something to do with a variable?

Notice also that it does not matter *what* kind of object a name
refers to: it may be a function, a class, an object instance,
whatever. Inside a function, by example, a local name "a" may be
bound at most to a single object at a time, it doesn't matter its
type. A local name "a" can't refer to an integer and a class at the same time.
The left hand side of an assign statement *always* uses local names,
except when you declare a name to be global by using the "global" keyword.
And notice also that I've never used the word variable.
Oh wait can I do this in Python?:
<code>
def a():
def b()
</code>

so the b() will appear to be a local function which is the possible
cause of my little own error because the compiler will interpret the
number() as a local function but a global one?

Yes, you can. Python has "lexically nested scopes". The simple
local/global rule of above is a bit more complicated: when a name is
not local, it is searched inside the enclosing functions, then in the
containing module's global namespace, and last in the builtin names.
And yes, b is local to a, so it effectively hides any external b that
could be in outer scopes.


--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
 
C

Camellia

Oh how can I thank you enough, you make my day:)
According to what you said I finally figure it out, it is the same as:

<code>
b = 1
def a():
b = b #no good:)
</code>

So in every day programming I should avoid using the same name for
different objects because they will step on each other, right?
 
C

Camellia

Oh how can I thank you enough, you make my day:)
According to what you said I finally figure it out, it is the same as:

<code>
b = 1
def a():
b = b #no good:)
</code>

So in every day programming I should avoid using the same name for
different types of objects because they will step on each other, right?
 
F

Fredrik Lundh

Camellia said:
Oh how can I thank you enough, you make my day:)
According to what you said I finally figure it out, it is the same as:

<code>
b = 1
def a():
b = b #no good:)
</code>

if you really want to modify a variable that lives outside the function,
you can use the "global" directive:

http://effbot.org/pyfaq/how-do-you-set-a-global-variable-in-a-function.htm
> So in every day programming I should avoid using the same name for
> different types of objects because they will step on each other,
> right?

if you want to distinguish between things, giving them distinct names is
always a good idea.

</F>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top