None weirdness

Steve Holden sholden at holdenweb.com
Mon Dec 2 10:20:21 EST 2002


"Ian McConnell" <ian at infosar.co.uk> wrote in message
news:wxvg2c8udl.fsf at velocita.nasoftware...
> Can someone explain what is going on here?
>
>
> #!/usr/bin/python2.2
>
> def main():
>     a = None
>     None = 1
>
> if __name__ == "__main__":
>     main()
>
>
> Traceback (most recent call last):
>   File "sub.py", line 8, in ?
>     main()
>   File "sub.py", line 4, in main
>     a = None
> UnboundLocalError: local variable 'None' referenced before assignment
> Exit 1
>
>
>
> Python seems to be doing the 'None=1' assignment before 'a=None'!
>
>
> If this seems like pretty weird code, then it resulted from me trying to
do
>         a, None = func()
>
> func() returns a pair of answers, but I was only interested in the first,
so
> I thought that "a, None" would just drop the second value. However, it
> redefined None.
>
> I now use
>         a, = func()
> which works, but doesn't seem as clear to me.

Noting that the function would execute without raising an exception if
EITHER line in the body were omitted, you might wonder why. The missing
information not so far mentioned in this thread is that the compiler
determines which names are locals by a static analysis of the program text.

Thus it knows "None" is local to main because of the assignment to it inside
the function body.

Remove the first statement and you aren't using a local before assigning to
it. Omit the second statement and "None" is no longer a local.

Also realise that the "None" you normally use lives in the built in
namespace, so the only way to truly overwrite it is with an assignment such
as

    __builtins__.None = 42

After that you might find that your interpreter behaves strangely under
certain circumstances, so the best advice is "Don't do that".  Instead of

    a, None = func()

use either

    a, dummy = func()

or

    a = func()[0]

It's clearly NOT a good idea to use

    a, = func()

because on recent Pythons that will give you an error:

Python 2.2.2 (#1, Nov 15 2002, 07:49:04)
[GCC 2.95.3-5 (cygwin special)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def func():
...     return (1, 42)
...
>>> a, = func()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: unpack tuple of wrong size
>>>

regards
-----------------------------------------------------------------------
Steve Holden                                  http://www.holdenweb.com/
Python Web Programming                 http://pydish.holdenweb.com/pwp/
Previous .sig file retired to                    www.homeforoldsigs.com
-----------------------------------------------------------------------






More information about the Python-list mailing list