Introduction To Scope In Python
❖ What is Name in Python?
Everything in Python is an object. Since everything is an object we need to identify and distinguish each type of object from one another and this is what a name does. Name is simply a unique name given to objects in Python so that they can be identified. For example, when a function is defined in a program, it is given a name that is used to identify the function. Another example is a simple variable assignment
var = 25. Here 2 is the object stored in the memory while var is the name given to the object.
❖ What is Scope?
The scope of a name like a variable, function, object, etc. is the region or part of the program where the name can be accessed directly. In other words, a name is visible and accessible only within its scope.
❖ What is Namespace?
A namespace is simply a collection of names. It is a container that contains the names mapped to their respective objects. Namespaces are isolated; thus same names within different scopes do not collide.
🐍 The namespace that contains all the built-in names is created by default because of which built-in functions like
print() can be accessed from all parts of the program.
name = "FINXTER" print("Name in Global Scope: ", name) def foo(): name = "PYTHON" print("Name in Local Scope: ", name) foo()
Name in Global Scope: FINXTER Name in Local Scope: PYTHON
In the above example, we can see that the variable is in the global namespace as well as inside the local namespace and does not collide. Now that brings us to a very important discussion on variable scopes and the LEGB rule of scope resolution.
The LEGB Rule And Variable Scopes
LEGB is an abbreviation for Local(L)-Enclosed(E)-Global(G)-Built-In(B) and it is used to define Python Scope resolution. Let’s understand what is scope resolution and how LEGB works.
Disclaimer: The LEGB rules are specific to variable names and not attributes.
❖ Local Scope (L)
When a variable/name is created inside a function, it is only available within the scope of that function and ceases to exist if used outside the function. Thus the variable belongs to the local scope of the function. Every time the function is called, a new local scope is created. Local scope is also called function scope.
def foo(): scope = "local variable" print(scope) foo()
❖ Enclosing Scope (E)
An enclosing scope occurs when we have nested functions. When the variable is in the scope of the outside function, it means that the variable is in the enclosing scope of the function. Therefore, the variable is visible within the scope of the inner and outer functions. Enclosing Scope is often called non-local scope.
def foo(): scope = "enclosed variable" def func(): print(scope) func() foo()
In the above example, the variable
scope is inside the enclosing scope of the function
foo() and available inside the
foo() as well as
❖ Global Scope (G)
A global variable is a variable that is declared in a global scope and can be used across the entire program; that means it can be accessed inside as well outside the scope of a function. A global name is generally declared outside functions, in the main body of the Python code. In the backend, Python converts the programs main script into the
__main__ module which is responsible for the execution of the main program. The namespace of the
__main__ module is the global scope.
name = "FINXTER" def foo(): print("Name inside foo() is ", name) foo() print("Name outside foo() is :", name)
Name inside foo() is FINXTER Name outside foo() is : FINXTER
❖ Built-In Scope (B)
The built-in scope is the widest scope available in python and contains keywords, functions, exceptions, and other attributes that are built into Python. Names in the built-in scope are available all across the python program. It is loaded automatically at the time of executing a Python program/script.
x = 25 print(id(x))
❖ Example Of Scoping Rules In Python
x = 100 print("1. Global x:", x) class Test(object): y = x print("2. Enclosed y:", y) x = x + 1 print("3. Enclosed x:", x) def method(self): print("4. Enclosed self.x", self.x) print("5. Global x", x) try: print(y) except NameError as e: print("6.", e) def method_local_ref(self): try: print(x) except UnboundLocalError as e: print("7.", e) x = 200 # causing 7 because has same name print("8. Local x", x) inst = Test() inst.method() inst.method_local_ref()
1. Global x: 100 2. Enclosed y: 100 3. Enclosed x: 101 4. Enclosed self.x 101 5. Global x 100 6. name 'y' is not defined 7. local variable 'x' referenced before assignment 8. Local x 200
The following diagram provides a pictorial representation of scopes rules in Python:
Understanding UnboundLocalError In Python
When a variable is assigned within a function, it is treated as a local variable by default in Python. If a local variable is referenced before a value has been assigned/bound to it, an
UnboundLocalError is raised. In the above example when the variable
'val' is read by the Python interpreter inside the
func() function, it assumes that
'val' is a local variable. However, it soon realizes that the local variable has been referenced before any value has been assigned to it within the function. Thus it throws an
In other words, we can only access a global variable inside a function but cannot modify it from within the function (unless you force a global or nonlocal assignment using the
val = 100 def func(): val = val + 100 print(val) func()
Traceback (most recent call last): File "C:/Users/Shubham-PC/PycharmProjects/pythonProject1/main.py", line 9, in <module> func() File "C:/Users/Shubham-PC/PycharmProjects/pythonProject1/main.py", line 5, in func val = val + 100 UnboundLocalError: local variable 'val' referenced before assignment
Resolution: To resolve an
UnboundLocalError when the local variable is reassigned after the first use, you can either use the
global keyword or the
nonlocal keyword. The
global keyword allows you to modify the values of a global variable from within a function’s local scope while the
nonlocal keyword provides similar functionality in the case of nested functions.
That brings us to a very important topic –
The global And nonlocal Keyword In Python
❖ The global Keyword
We already read about the global scope where we learned that every variable that is declared in the main body and outside any function in the Python code is global by default. However, if we have a situation where we need to declare a global variable inside a function as in the problem statement of this article, then the global keyword comes to our rescue. We use the
global keyword inside a function to make a variable global within the local scope. This means that the global keyword allows us to modify and use a variable outside the scope of the function within which it has been defined.
Now let us have a look at the following program to understand the usage of the
def foo(): global name name = "PYTHON!" print("Name inside foo() is ", name) foo() name = "FINXTER "+name print("Name outside foo() is ", name)
Name inside foo() is PYTHON! Name outside foo() is FINXTER PYTHON!
❖ The nonlocal Keyword
nonlocal keyword is useful when we have a nested function, i.e., functions having variables in the enclosing scope. In other words, if you want to change/modify a variable that is in the scope of the enclosing function (outer function), then you can use the
nonlocal keyword. If we change the value of a
nonlocal variable the value of the
local variable also changes.
def foo(): a = 25 print("Value of 'a' before calling func = ",a) def func(): nonlocal a a=a+20 print("Value of 'a' inside func = ",a) func() print("Value of 'a' after exiting func = ",a) foo()
Value of 'a' before calling func = 25 Value of 'a' inside func = 45 Value of 'a' after exiting func = 45
❖ Global Keyword vs Nonlocal Keyword
Before concluding this article, let us have a look at the key differences between a
- Unlike the
nonlocalkeyword works only in Python 3 and above.
globalkeyword can be used with pre-existing global variables or new variables whereas the
nonlocalkeyword must be defined with a pre-existing variable.
In this article we learned the following:
- What are names in Python?
- What are namespaces in Python?
- What are scopes in Python?
- The LEGB Scope Resolution Rule in Python.
- The UnboundLocalError.
- The Global and Nonlocal Keyword.
Where to Go From Here?
Enough theory, let’s get some practice!
To become successful in coding, you need to get out there and solve real problems for real people. That’s how you can become a six-figure earner easily. And that’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?
Practice projects is how you sharpen your saw in coding!
Do you want to become a code master by focusing on practical code projects that actually earn you money and solve problems for people?
Then become a Python freelance developer! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.
Join my free webinar “How to Build Your High-Income Skill Python” and watch how I grew my coding business online and how you can, too—from the comfort of your own home.