Okay this question might need a little bit of explaining.
PEP 3104 states that:
In most languages that support nested scopes, code can refer to or rebind (assign to) any name in the nearest enclosing scope. Currently, Python code can refer to a name in any enclosing scope, but it can only rebind names in two scopes: the local scope (by simple assignment) or the module-global scope (using a global declaration).
Two things you must understand here is that:
Binding: create a name, bind a value to it.
e.g:>>> a=10
creates a variable a and assigns 10 to it.
Rebinding: change the value bound to the name.
e.g:
>>> a=10;a=5
binds value 10 then rebinds 5 to 'a' itself.
So as it is clearly stated it can only rebind name in the local scope.
Example:
def func():
a=5
print(a)
a=10
print("a in the program")
print(a)
print("a in func()")
func()
output:
a in the program
10
a in func()
5
Now remove a=5
from func()
and you get:
a in the program
10
a in func()
10
What happens is a
is found out to be 10
and it is printed.
Now do this:
def func():
print(a)
a=5
a=10
print("a in the program")
print(a)
print("a in func()")
func()
you get this:
UnboundLocalError: local variable 'a' referenced before assignment
What happens if you give a=5
in a function?
No rebinding occurs now instead a new local variable a=5 is created.
So,
if you don't write a=5
after/before print
statement it just prints the global variable a
by default.
However if you write a=5
before print(a)
it creates a local variable a
and then binds (note: not rebind but binds) the value 5
to it.
But if you write a=5
after print(a)
it gets confused as to why you are referencing a variable(local variable a) which hasn't yet been created.
However, because any assignment to a name implicitly declares that name to be local, it is impossible to rebind a name in an outer scope (except when a global declaration forces the name to be global).
So if you use global a
the print(a) happily prints the global a
as 10
and then creates a new local variable a=5
by binding 5 to a.
global a
print(a)
a=5
print(a)
output:
def func():
global a
print(a)
a=5
print(a)
a=10
print("a in the program")
print(a)
print("a in func()")
func()
But this is not the case with your other objects like list
,dict
and such.
In this case, you're just modifying an existing, global object, which is found by regular name lookup (changing a list entry is like calling a member function on the list, it's not a name rebinding).
So it works fine without any errors. Hope you understood something.