Tkinter WEIRDNESS or Python WEIRDNESS?

Brian van den Broek bvande at po-box.mcgill.ca
Sat Mar 12 19:34:33 EST 2005


steve said unto the world upon 2005-03-12 18:46:
> Brian van den Broek <bvande at po-box.mcgill.ca> wrote in message news:<mailman.312.1110609301.1799.python-list at python.org>...
> 
>>steve said unto the world upon 2005-03-12 00:06:
>>
>>>In a nutshell, my problem is that I am getting this runtime error, and
>>>I have no clue why.  Please bear in mind its my first python program:
>>>
>>>"localvariable 'currentAbility' referenced before asignment"
>>>
>>>in this function which is a callback for a button:
>>>now the thing is, both lookingAtAbilities  and  currentAbility are
>>>global variables.  In fact, they are both assigned at the same part of
>>>the program, right at the start.  yet lookingAtAbilities  is
>>>recognized as a global by this function, and currentAbility is not,
>>>generating this runtime error.
>>>
>>>here is the structure of the code:
>>
>><SNIP>
>>
>>>This has me flumoxed
>>>
>>>thanks if you can work it out,
>>>
>>>Steve
>>
>>Hi Steve,
>>
>>While both lookingAtAbilities and currentAbility are names in the 
>>global namespace, nextThing() doesn't know that ;-).
>>
>>The first mention of if lookingAtAbilities in nextThing() is:
>>.    if lookingAtAbilities == 1:
>>This is a reference to the name, so the interpreter fetches 
>>lookingAtAbilities value from the first namespace in which it finds 
>>such a name. (The global namespace.)
>>
>>By contrast, the first mention of currentAbility is:
>>.        currentAbility = currentAbility + 1
>>So, the interpreter `creates' (I am a bit fuzzy on the terminology and 
>>not an accomplished Pythoner) a name in the function local namespace 
>>and then looks to see what value to point the name at. When it sees it 
>>should have currentAbility (a name without a value as yet) point to
>>currentAbility + 1, it barfs.
> 
> 
> Thanks to both of you, this has fixed the problem.  I wouldnt have
> guessed that in a million years.

Hi Steve,

you're welcome. I'm just glad I've finally understood enough to offer 
helpful answers :-) (Though note the self-correction at the end of 
this post.)

> But it leads me to ask what is the use of something being in the
> gloabl namespace if it cant be accessed globally?

I think that your question shows there is some residual confusion. 
Things in the global namespace can be accessed just fine. The issue 
with your code was that, while you had a global name currentAbility in 
the global namespace sitting around just waiting to be accessed, your 
first use of that name in your function was to assign it.

Assignments are by default to names in the local namespace. If you'd 
put the global line in, you'd have told the interpreter to make the 
assignment in the global scope. Without this, your function told the 
interpreter to create a new name in the local namespace and make it 
refer to the object to the right of the '=' which, in your case, was 
not well-defined.

There is a certain logic to making assignments be assignments within 
the active namepace by default. There may be a deeper reason, but I 
don't know it. (To anyone more expert: if there is, I'd love to learn it).

> I also find the continual need for objects to reference their own
> variables by prefixing 'self' annoying.  It seems that Python is the
> reverse of my assuptions.  whats the rationale for that?

The self prefix is just a conventional way of indicating a reference 
to the current class instance. I hated it at first too. Python is my 
first language since some BASIC long ago and the selfs were one reason 
I steered clear of OOP at first. But, a few evenings of programming 
with classes (a recent thing for me) and the aversion went away. So: 
give it a bit of time; you might get so you aren't bothered by them.

I should also note there was some residual confusion in what I wrote, too:

>>Still another (but one not so good for clarity or beauty) would be to 
>>put a line like:
>>temp = currentAbility # temp a name to reference global scope name
>>                       # before assignment to follow.

This won't work. Witness:

 >>> a = 42
 >>> def my_mistake():
... 	temp = a
... 	a = a * 2
... 	
 >>> my_mistake()
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
   File "<interactive input>", line 2, in my_mistake
UnboundLocalError: local variable 'a' referenced before assignment
 >>>

Sorry 'bout that :-[

Best,

Brian vdB




More information about the Python-list mailing list