Newby Coder header banner

Python Scope and Namespace

Python Namespace

A namespace is a collection of namesIn Python, a namespace can be inferred as a mapping of every identifier(or name) defined to corresponding objects

Python Identifiers

Identifier is simply a name given to objects, used to access the underlying object

Most things in Python(like class, strings, numbers etc) are objects

For example, in the assignment x = 4, 4 is an object stored in memory and x is the identifier(or name) associated with it

The address (in RAM) of objects can be retrieved through the built-in function id()

x = 4
print('id(x) =', id(x))
print('id(4) =', id(4))

Output

id(x) = 10914592
id(4) = 10914592

Python Namespace

Namespace is like a mapping of identifiers and their corresponding objects

Different namespaces can co-exist at a given time while being isolated

A namespace containing all the built-in identifiers is created when Python interpreter is started and exists as long as the interpreter runs

This makes the built-in functions like id(), print() etc. available to any part of a program

Each module (or Python file) creates its own global namespace (when run for a program)

These namespaces are isolated allowing same identifier to exist in different namespaces while associating with different objects

A local namespace is created when a function or a class is called, which has all the identifiers defined in it

cl-python-namespace

Python Variable scope

A scope is the portion of a program from where a namespace can be accessed directly without any prefix.At any given moment, there can be about three nested scopes

Similarly a class has an associated scope

Although there can be various unique namespaces defined, all of them might not be accessible from every part of a program

When a reference is made inside a function, the name is searched in the local namespace, then in the global namespace and finally in the built-in namespace

If there is a function inside another function, a new scope is nested inside the local scope

Example

def outer():
    y = 20
    def nested():
        z = 10

x = 30

Here

If in nested(), a value is assigned to y, a new variable y is created in its local namespace which is different than the nonlocal y

Same thing happens when a value is assigned to x inside nested()

x, being a global variable can be read inside the functions

def outer():
    y = 20
    print("x inside outer():", x)
    def nested():
        z = 10
        print("x inside nested():", x)
    nested()

x = 30
print("x:", x)
outer()

Output

x: 30
x inside outer(): 30
x inside nested(): 30

But x cannot be modified inside the functions if not declared locally

def outer():
    y = 20
    x = x + y
    print("x inside outer():", x)
    def nested():
        z = 10
        print("x inside nested():", x)
    nested()

x = 30
print("x:", x)
outer()

Output

x: 30
Traceback (most recent call last):
  File "<scope.py>", line 1, in <module>
  File "<scope.py>", line 3, in outer
UnboundLocalError: local variable 'x' referenced before assignment

Python shows UnboundLocalError in such case

To modify an identifier declared in global namespace inside a function, global keyword has to be used to declare the identifier as global inside the function

More on global, local and nonlocal variables