unintuitive for-loop behavior
Chris Angelico
rosuav at gmail.com
Thu Sep 29 19:19:09 EDT 2016
On Fri, Sep 30, 2016 at 5:29 AM, <namenobodywants at gmail.com> wrote:
> i've had a nodding acquaintance with python for some time, and all along i assumed that for-loops got a namespace of their own; now i'm reading up on the language and i find out that's not the case: the loop variable gets put into the enclosing namespace, overwriting any former value that was already there; of course i realize there are situations where one is interested in the value that a loop variable has after the loop has been exited, but this behavior seems grossly unintuitive to me: has there ever been any discussion of giving for-loops the option of running in namespaces of their own?
>
No, there hasn't. In Python, there are no sub-function scopes - even
the couple of cases that look like subscopes (list comps and genexps)
are actually implemented as nested functions (fairly obvious in the
case of a genexp, more subtle with the list comp). C-like languages
can have infinitely nested scopes because they have variable
declarations:
int some_func() {
int foo;
for (...) {
if (whatever) {
foo = 1234;
} else {
foo = 2345;
}
use(foo);
}
}
The placement of 'int foo;' determines the scope of that name. Python
doesn't have that, so your options are:
1) The first assignment to a name determines its scope. That would
mean that the two assignments are in different scopes, and use(foo) is
not included. To solve this, you'd need a dummy assignment further up
(eg where "int foo" is) - not impossible but probably annoying.
2) Have a single and simple scoping rule, like "anything that's
assigned to is function-local".
Python chose the second option. Anything you assign to is local to the
function, but nothing narrower. There is no way [1] to have a local
name in a function AND use a global with the same name, even in
different parts of the function. Since a 'for' loop is assignment
("for X in Y" assigns to X), that name has to be function-scoped. You
could, in theory, have the name be unbound after the loop, but it's
usually not beneficial to do so, and can be detrimental.
ChrisA
[1] Well, you can use globals(), but that's not quite the same thing
as variable scope.
More information about the Python-list
mailing list