Easy questions from a python beginner

geremy condra debatem1 at gmail.com
Mon Jul 12 00:10:09 EDT 2010


On Sun, Jul 11, 2010 at 10:39 PM, Steven D'Aprano
<steve-REMOVE-THIS at cybersource.com.au> wrote:
> On Mon, 12 Jul 2010 03:12:10 +0200, Alf P. Steinbach /Usenet wrote:
>
>> * MRAB, on 12.07.2010 00:37:
> [...]
>>> In Java a variable is declared and exists even before the first
>>> assignment to it. In Python a 'variable' isn't declared and won't exist
>>> until the first 'assignment' to it.
>>
>> That is a misconception.
>>
>> In Python a variable is declared by having an assignment to it, which
>> for a local variable may be anywhere within a routine.
>
> Oh, I'm going to regret being sucked into this...
>
> In *CPython*, but not necessarily other implementations, variables which
> are local to a function are not kept in a dictionary-based namespace, but
> in slots in the code object (not to be confused with __slots__ used for
> classes). Python has STORE_FAST and LOAD_FAST byte-codes for accessing
> locals.
>
> This is intended as a speed, and possibly memory, optimization. I don't
> believe this is a requirement though, so implementations may not do this.
>
> It is true that the slot is created at compile time, and in *that sense*,
> local variables exist before they are bound. I'm not entirely convinced
> that this is the only sense that matters, but never mind. The error
> message given exposes this to the user:
>
>>>> def f():
> ...     print x
> ...     x = 1
> ...
>>>> f()
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
>  File "<stdin>", line 2, in f
> UnboundLocalError: local variable 'x' referenced before assignment
>
>
> If you try this with a global, you get this:
>
>>>> def f():
> ...     global x
> ...     print x
> ...
>>>> f()
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
>  File "<stdin>", line 3, in f
> NameError: global name 'x' is not defined
>
> In this case, there's no doubt that global variable "x" doesn't exist at
> all -- there is no key "x" in the global namespace.
>
>
> It seems to me that "a slot to hold the variable is created for local
> variables" is an implementation detail, not a language feature. CPython
> could easily hide the difference by changing the exception from
> UnboundLocalError to:
>
> NameError: local name 'x' does not exist
>
> and nobody would be any wiser. (Well, perhaps people who catch
> UnboundLocalError, but why would you do that?)
>
> I also note that UnboundLocalError is a subclass of NameError, so
> "variable exists but is not bound" is considered to be a special case of
> "variable doesn't exist" rather than a completely independent case. In
> that sense, I think I'm on solid ground to say that in Python variables
> don't exist until they are bound to a value, and leave it to pedants like
> you and I to mention that for CPython local variables have space reserved
> for them by the compiler before they are bound.

Very interesting, and a pleasant change of tone to boot. Thanks.

Geremy Condra



More information about the Python-list mailing list