Who here thinks Python should have block scope of variables declared and initialized in loop-control structures and decision-structures like while-loops, for-loops and if-elif-else statements?
Shouldn’t this go to ideas?
I moved it to Python Help (“General help/discussion forum for the Python programming language”). Based on previous discussions in Ideas, this one may be a bit underbaked for fruitful discussion.
The following are a couple of discussions in which it was generally felt that the Ideas category should be reserved for proposed changes to Python that had been carefully considered and therefore could be elaborated in some reasonable level of detail:
You would need to use nonlocal
:
def outer():
x = 10
def inner():
nonlocal x # Refers to the 'x' in the outer function's scope
x = 5 # Modifies the outer 'x'
print("Inner x:", x) # Prints 5
inner()
print("Outer x:", x) # Prints 5 (outer 'x' is modified by inner)
outer()
Programming languages that support block scope also have variable declarations:
int x; // Declaration
x = 10; // Initialization
In Python, you cannot reassign a variable without actually shadowing it.
We see a notice indicating that this is your first post on this forum, so welcome to the Python community, @pythonic-guru!
You might be interested in looking at the following information, which may enhance your benefit from the discussions here:
Also please take a casual browse through the various categories to get a general view of what is happening here.
With regard to block scope of variables initialized in loops, there was an informal poll here several years ago:
Note that with 128 voters, the results were as follows:
- 80%: No change, leave loops as they are.
- 11%: Change loops to use their own scope.
- 9%: No change for loops by default, but add an option to run them in a new scope.
So, it currently seems a bit of a climb to gain acceptance for that proposal.
I don’t think you quite understand my question,
I was talking about while-loops, for-loops and if-elif-else statements having no block scope - not function definitions.
Please consider reading my original question again.
Thank you for taking the time to respond.
I write a lot of Java, which has these semantics. I like that j
exists only while I need it in the following:
if (kwnames != null) {
kwargs = Py.dict();
int j = start + nargs;
for (Object name : kwnames)
kwargs.put(name, stack[j++]);
}
but it I miss Python when I have to declare ar
just so it exists up to the return statement in:
PyTuple ar;
if (args instanceof PyTuple) {
ar = (PyTuple)args;
} else {
ar = PyTuple.EMPTY;
}
return call(callable, ar, kw);
Can’t have both. Happy working in either way.
Hi Jeff,
Thanks for taking the time to reply to my question but I am having trouble seeing how your reply helps me with my problem in Python.
To aid the discussion you could provide us with a concrete example of something specific you would like to be able to do with block scoping of variables.
You asked “who here thinks …”. Based on experience of Python (obviously) and writing real code in a language with the feature (see examples), sometimes I appreciate that feature (because of the safety), sometimes I am irked it is not lilke Python (because now I have to declare a variable).
I see your point, but it doesn’t make me want to see Python changed as you propose.
For example, it would be safer to use a variable inside the local scope of a for-loop ONLY with the developer assured that use of a variable with same name outside the for-loop local scope would not have contents determined by what has happened to it inside the for-loop local-scope.
It would be great if you could post some Python code to exemplify this, along with a brief explanation of how you would like it to work. Please make sure the code is formatted properly for posting, as is explained in the first of the two documents that is linked from post 6 of this discussion. We need to make sure that the indentation that defines the code blocks is displayed properly. Even if the proposed feature is not adopted, your example could facilitate this discussion.
I’d definitely use const
and let
keywords in Python. Instead of everything being scoped like var
(in JS terms). It’s currently possible to simply del
a variable where it would’ve gone out of scope in another language. Few bother to do so.
Are you talking about adding this as an opt-in feature, or fundamentally redesigning how scope works in Python at this late stage?
Here is an example of code which could benefit from having block-scope in for-loops in Python:
a = 0
a += 1
print(a)
for i in range(3):
if i == 0:
a = 0
else:
a += i
print(a)
a += 2
print(a)
So as Python exists at the moment we would expect to see the following output in the PyCharm console:
1
0
1
3
5
But if block-scope was available in Python then the output would be:
1
0
1
3
3
So we see here that not having block-scope of variable a
in the for-loop allows the variable’s contents to be changed, the same variable that was initialised to zero at the start outside the local scope of the for-loop.
After the for-loop has completed execution, the variable a
now has contents that are different from before the loop executed and the variable contents are now changed again.
I think it can be clearly seen that, like other programming languages, it is safer to use variables inside the local-scope of a for-loop purely for the purposes of carrying out the task(s) inside the for-loop alone, without manipulating a variable with the same name outside the for-loop scope.
After fixing the two syntax errors, it actually prints:
1
0
1
3
5
If this is a serious discussion, a much better example is needed.
Thank you for your reply.
I could only see one syntax error, in
was missing from the for-loop statement.
I did delete one space character before the print(…)
function call in the for-loop.
Please review my example code now and say why it doesn’t illustrate the problem with no block scope in a Python for-loop.
It doesn’t illustrate a problem. It illustrates a distinction. You have shown that the semantics of variable name reuse are different depending on whether the inner variable is the same one as the outer, or is a separately-scoped one. We know this. Many of us DO have experience with other languages.
Can you illustrate a problem here? Can you show where something needs to be changed?
Are you able to understand from my example that without block scoping in a Python for-loop the variable a
initialised to 0
before the for-loop executes can be changed inside the for-loop?
Yes, of course. And to save time, we also understand that the programmer has made the mistake of using as a temporary variable, the same name they used outside the loop for something else, assuming the value would be preserved.
I think we’re just not finding it a very likely kind of mistake.
Edit: I think I could come up with a more compelling example, but good practice or a linter is likely to prevent that too. Hence the challenge for you to come up with a compelling, realistic, example.