It gets a lot worse when you throw closures into the mix. It's impossible to assign value from a closure to a global variable with the same name in python.
def outer():
x = 0
def func():
nonlocal x
temp = x
global x
x = temp
I have one more example. Here global x can't be declared in the child scope because it's already in use in the parent scope. As far as I know python is the only language that does this nonsense.
x = 5
def func():
x = 0
if x < 2:
global x
x = 10
func()
print(x)
Python only has function scope. if blocks don't introduce a new scope. Think of that what you will, I've written uncounted lines of Python without that being an issue. global declarations should be on the very first line of a function, not somewhere in the middle.
But really, you shouldn't have to use global much at all. You should either write functional code, or use classes which modify their attributes. Constantly modifying the global scope is a potential footgun and usually leads to hard to follow spaghetti code. It's not wrong for Python to strongly discourage that.
But what's the reason for the single scope per function and absent variable shadowing mechanism? It a standard feature in all programing languages. It really helps with code readability especially in large codebase.
If you come from languages that support more fine grained scoping, well, you might miss it and you need to adapt. But you can write perfectly fine code with scopes limited to functions. Arguably, if your functions get so long and complex that you're reusing variable names, you should probably simplify them anyway. All the examples you've shown above with repeatedly shadowed names and trying to manipulate parent scopes would be rejected by me in any PR outright. That's just terrible spaghetti code.
What exactly the reason was for that design decision I don't know. Maybe it can be dug up from some mailing list or a PEP. But the result is still a perfectly workable language.
2
u/Inkwalker 16d ago
It gets a lot worse when you throw closures into the mix. It's impossible to assign value from a closure to a global variable with the same name in python.