Any enclosing variable can be shadowed in the local scope with | Python etc
Any enclosing variable can be shadowed in the local scope without affecting the global one:
v = 'global' def f(): v = 'local' print(f'f {v=}') f() # f v='local'
print(f'{v=}') # v='global'
And if you try to use a variable and then shadow it, the code will fail at runtime:
v = 'global' def f(): print(v) v = 'local' f() # UnboundLocalError: local variable 'v' referenced before assignment
If you want to re-define the global variable instead of locally shadowing it, it can be achieved using global and nonlocal statements:
v = 'global' def f(): global v v = 'local' print(f'f {v=}') f() # f v='local' print(f'g {v=}') # g v='local'
def f1(): v = 'non-local' def f2(): nonlocal v v = 'local' print(f'f2 {v=}') f2() print(f'f1 {v=}') f1() # f2 v='local' # f1 v='local'
Also, global can be used to skip non-local definitions:
v = 'global' def f1(): v = 'non-local' def f2(): global v print(f'f2 {v=}') f2() f1() # f2 v='global'
To be said, using global and nonlocal is considered a bad practice that complicates the code testing and usage. If you want a global state, think if it can be achieved in another way. If you desperately need a global state, consider using singleton pattern which is a little bit better.