I’m not able to find any explanation about scope of variables inside loops in Python as opposed to “block-level” scope in C/C++. Should this be mentioned somewhere in chapter 9.2 of The Python Tutorial or somewhere else ?
I think it would be useful for people with prior experience in C/C++.
Python’s scoping really works in the opposite way. While in C/C++ any set of braces creates a scope, in Python only certain things create a scope: function definitions, class definitions, lambdas, comprehensions and generator expressions.
So loops don’t affect scoping at all, they’re have the same effect as an assignment.
A scope is a textual region of a Python program where a namespace is directly accessible. “Directly accessible” here means that an unqualified reference to a name attempts to find the name in the namespace.
Although scopes are determined statically, they are used dynamically. At any time during execution, there are 3 or 4 nested scopes whose namespaces are directly accessible:
the innermost scope, which is searched first, contains the local names
the scopes of any enclosing functions, which are searched starting with the nearest enclosing scope, contain non-local, but also non-global names
the next-to-last scope contains the current module’s global names
the outermost scope (searched last) is the namespace containing built-in names
Only those scopes, regardless of any other constructs you use.
For some people, Python is the first algorithm/computer language. Others have a wide variety of backgrounds. We are currently removing specific references to other languages (Pascal and C) since they are useless or even confusing to many.
I’m generally in favor of describing Python on its own terms, rather than in contrast to other languages thought of as the default. But in this case, I think a simple mention could help people understand Python. Something like:
Note that unlike many other languages, blocks in Python do not create a new scope. Variables defined in loops or if statements are available outside of those blocks.
Helpfully (or not), this is not true of comprehensions.
By the way, I’m of the opinion that scoping is a valuable topic, and
maybe should stand on its own, rather then be buried in the tutorial
chapter on classes…
It definitely should be explained before classes, because it affects ordinary functions. Really, it should be explained way back there (chapter 4). (Some people even get the idea of nesting functions, way before they have a real use case for it.)