You will learn about Python scopes and how they are used to define the accessibility of objects, namespaces or variables in Python.
Python keeps track of every variable defined in a program as well as the values they are associated with. Though you can define a variable anywhere you wish to, the accessibility of that variable depends on where it was defined.
Let’s say that you defined a variable is defined at the top level of a program. Since Python programs are executed from top to bottom, every line of code written after that variable can access it.
On the contrary, if it were to be defined inside a function or class, it is only accessible in the function or class. Outside the function or class, it is invisible.
What is scope in Python?
The scope of a variable refers to places where the variable is visible or can be accessed by other variables or statements in a program. Scope defines the accessibility of Python objects or namespaces in Python.
Essentially, every variable is associated with a value in Python. By specifying a variable name, you retrieve or access the value associated with that variable.
In a situation where there are so many variables with the same name, scope determines the exact variable that you are interested in.
Python searches through different scope levels to determine which variable you are referring to and whether it is accessible or not.
LEGB Rule in Python
Imagine that you have a program containing two variables with the same name – avg.
One is defined as a top-level variable and the other is defined inside a function.
#avg as a top-level variable avg = 1.5 def calc(num1, num2): #avg inside a function avg = (num1 + num2)/2
Since the two variables bear the same name, it becomes difficult distinguishing between the two at certain points in the program.
In resolving this issue, python uses the LEGB rule to resolve conflicts of namespaces and values.
LEGB rule stands for Local, Enclosed, Global and Built-in and is a lookup procedure that determines the order in which Python looks up names.
Hence, whenever you call a variable or namespace, python uses this rule to determine whether it’s available in the first place.
If more than one name shows up, it resolves the conflict by choosing the first name to show up. This is done using the LEGB rule in the order of Local, Enclosed, Global and Built-in.
Local scope
Local scope, also known as function scope is found in variables that are defined inside of a function. The variable is only visible within the function, and invisible in every other place.
def func(): #local scope num=10 print(num) #outside the function func() #Accessing the variable outside the function you will get an error print(num)
In the above example, the variable num has a local scope since it is defined inside of a function func. Trying to access the variable outside the function is impossible.
Enclosing scope
Enclosing or non-local scope is a kind of scope that is nested in functions. If a variable is defined inside a given function, it is only accessible or visible inside that function and in other functions enclosed in it.
num = 5 def outer_func(): #local scope num=10 def inner_func(): #The scope of num is enclosing scope print(num) outer_func() #output #10
In the above example, starting from top to bottom, the variable num is defined with the value of 5.
However, in the function outer_function, the variable num is assigned a value of 10.
Using the LEGB rule, python looks up the value of num in the enclosing scope and if not found, it proceeds to the global scope.
Hence, the output from the function shows that the variable num, which is defined in the enclosing function outer_func is selected.
Global scope
In the global scope, the variable is seen everywhere. Global scope, otherwise known as module scope is accessible anywhere in the program.
Variables that are defined at the top level of modules are said to have global scopes.
#top level variable num = 10 print(num) #output - 10 def func(): print(num) func() #output - 10
Built-in scope
This refers to names such as keywords and namespaces that are built into the Python installation. If a name cannot be found in the local, enclosing and global scope, it is then searched for in the built-in scope.
round(10.5)
The above example passes an argument – 10.5 into a function named round(). Since no function is defined with such a name in the program, it looks up the name – round in the standard library – which is one of the built-in methods in Python.
global Keyword
Normally, if you define a variable in a function, the variable has a local scope. In some programming languages, assigning values to a variable with the same name as that in the global scope alters the values of the global variable.
However, in Python, this is not the case.
Local variables only exist in the function where they are defined and invisible in every other place. To be able to alter or modify a global variable, you have to specify that it is so using the global keyword.
This keyword is used to refer to a given variable with a global scope in a function. This allows you to reassign values or alter them in functions and not be treated as a local variable.
#Global scope num = 20 def func(): global num num=10 print(num) func() #output #10 print(num)
nonlocal Keyword
Just like the global variables, variables defined as a local variable is visible inside the function and enclosing function.
If it happens that you want to alter the value in an enclosing function, you have to specify that the variable you are referring to is the one in the enclosing function using the keyword nonlocal.
def outer_func(): #local scope num=10 def inner_func(): nonlocal num print(num) inner_func() outer_func() #output #10
In the function – outer_func(), num is defined as a local variable with a value of 10. This means that the value of the variable is 10 within the function.
However, variables with local scopes are visible within an enclosing function. So, if you want to change the value of the num to another value, this is what you will do.
You have to instruct the interpreter that the variable you want to change is still the same variable in the enclosing function.
This is done using the keyword nonlocal.