On Sun, Jul 11, 2010 at 10:39 PM, Steven D'Aprano <steve-remove-t...@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 -- http://mail.python.org/mailman/listinfo/python-list