Variables Scope
Taking as example, this code:
>>> num = 2
>>> def var_scope(num_fun):
... print(num_fun)
... try:
... print(num)
... num = 10
... except BaseException as err:
... print(err)
>>> var_scope(5)
5
cannot access local variable 'num' where it is not associated with a value
You may notice that print(num_fun)
was executed successfully, while print(num) raised an exception
, even though num was initialized outside the function
. The reason behind this is that when Python compiles the function's body, it identifies num as a local variable because it gets assigned within the function
. So, when the function var_scope is called
, it can access and print the value of the local variable num_fun
. However, when it attempts to access the local variable num, it encounters an issue because b is not bound
.
In Python, there's no requirement to declare variables explicitly
, but the interpreter assumes that a variable assigned within a function is local
. If you want the interpreter to treat b as a global variable and still assign a new value to it within the function, you need to use the global declaration.
>>> num = 2
>>> def var_scope(num_fun):
... global num
... print(num_fun)
... try:
... print(num)
... num = 10
... except BaseException as err:
... print(err)
>>> var_scope(5)
>>> print(num)
5
2
10
Types of Scope
-
Module Global Scope
Made of names assigned to valuesoutside of any class or function block
. -
Function Local Scope
Made of names assigned to values asparameters, or directly in the body of the function
. -
Nonlocal Scope
The nonlocal scope refer to all those variables that aredeclared within nested functions
. Thenonlocal keyword is used to work with variables inside nested functions
, where the variable should not belong to the inner function. It lets you declare a variable as afree variable
.
Variable Lookup Logic
When defining a function, the Python decides how to access a variable like x
within it, following these rules for each situation:
Referenced and Assigned
- If there's a
global x
declaration, the x variable isfetched from and assigned to the global variable x in the module
; - When a
nonlocal x
declaration is present, x istaken from and assigned to the local variable x
within the closest surrounding function where x is defined; - If
x is either a parameter or assigned a value within the function body
, it becomes the local variable.
Just Referenced and is not a Parameter
- x will be
searched in nonlocal scopes
. So, in the local scopes of the enclosing function bodies; - If not in nonlocal scopes, x will be
searched in the module global scope
; - If not in module global scope, x will be
searched in the __builtins__.__dict__
;
Comparing bytecodes
>>> num = 2
>>> def var_scope_right(num_fun):
... global num
... print(num_fun)
... try:
... print(num)
... num = 10
... except BaseException as err:
... print(err)
>>> def var_scope_wrong(num_fun):
... print(num_fun)
... try:
... print(num)
... num = 10
... except BaseException as err:
... print(err)
>>> from dis import dis
>>> print(dis(var_scope_right)) # Don't know why is not working
>>> dis(var_scope_wrong) # Don't know why is not working
None