0% found this document useful (0 votes)
2 views1 page

Namespaces in Python

Namespaces in Python are systems that hold collections of names and their corresponding objects, helping to organize variables and avoid conflicts. There are four types of namespaces: built-in, global, local, and enclosing, each with specific scopes and accessibility rules. The LEGB rule defines the order in which Python looks for names: Local, Enclosing, Global, and Built-in.

Uploaded by

ashwin choudhary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views1 page

Namespaces in Python

Namespaces in Python are systems that hold collections of names and their corresponding objects, helping to organize variables and avoid conflicts. There are four types of namespaces: built-in, global, local, and enclosing, each with specific scopes and accessibility rules. The LEGB rule defines the order in which Python looks for names: Local, Enclosing, Global, and Built-in.

Uploaded by

ashwin choudhary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1

Session 23 : Namespaces in Python

Namespaces
Namespaces in Python are essential concepts that refer to a system that holds a collection of names as keys and their corresponding objects as values. They are used to organize variables and avoid conflicts by creating separate, distinct regions for different names.

A namespace is a space that holds names(identifiers).


programically namespace are dictionary of identifiers and their objects

In [ ]: a=2
b=3

{a:2}

{b:3}

Types of Namespaces in Python


1. Built-in Namespace

Contains built-in functions and exceptions that come with Python, such as print() , len() , and Exception .
This namespace is loaded when the Python interpreter starts and is available globally in any part of the program.
2. Global Namespace

Contains names defined at the level of the main program, or names defined in a module imported into the main program.
Variables, functions, and classes declared outside of functions or classes are part of the global namespace.
Each module has its own global namespace.
3. Local Namespace

Created for each function or method call.


Holds names defined inside a function or method.
The scope of these names is limited to the function, meaning they are only accessible within that function.
4. Enclosing Namespace (Nonlocal)

Created when there are nested functions. If a function is defined inside another function, it has access to the outer function’s namespace.
Variables in the enclosing function are part of the enclosing (nonlocal) namespace for the inner function.
Uses the nonlocal keyword to modify variables from the outer function scope.

Namespace Hierarchy and the LEGB Rule


When Python encounters a name, it follows the LEGB Rule to resolve it:

1. Local: Checks the innermost scope (local to the function or method).


2. Enclosing: Checks any enclosing function’s namespace, if present.
3. Global: Checks the module-level namespace.
4. Built-in: Checks the built-in namespace for any built-in functions or variables.

Scope and LEGB Rule


A scope is a textual region of a Python program where a namespace is directly accessible. The interpreter searches for a name from the inside out, looking in the local, enclosing, global, and finally the built-in scope. If the interpreter doesn’t find the name in any of these locations, then
Python raises a NameError exception.

Global Scope and Local Scope


In Python, the global scope is the top-level scope in which variables are defined outside of any functions or classes. Variables in the global scope are accessible from any part of the code, including within functions and classes, unless shadowed by a local variable of the same name.

In Python, local and global scopes define where variables are accessible within a program.

Local Scope
A local scope is the region within a function or block of code where variables created within that block are accessible. Variables created in a local scope are called local variables, and they only exist during the execution of that specific function.

Lifetime: Local variables are only available while the function is running and are destroyed once the function completes.
Isolation: Each function has its own local scope, so variables within one function do not affect variables within another function, even if they share the same name.

Global Scope
A global scope is the region where variables are accessible throughout the entire program, including inside and outside functions. Variables created outside of any function or block are considered global variables, and they are accessible from any function in the program unless
shadowed by a local variable of the same name.

Lifetime: Global variables exist for the duration of the program.


Access in Functions: To modify a global variable inside a function, you must declare it with the global keyword.

Key Differences
1. Accessibility:

Local variables: Only accessible within their defining function.


Global variables: Accessible throughout the program.
2. Lifetime:

Local variables: Exist only during the function's execution.


Global variables: Exist throughout the program's lifetime.
3. Declaration:

Local variables: Declared inside functions or blocks.


Global variables: Declared outside any function or block.

In [1]: # global VS local

a=2 #global variable

def temp():
b=3 #local variable
print(b)

temp()
print(a)

3
2

In [3]: # local and global -> same name

a=2 #global variable

def temp():
a=3 #local variable
print(a)

temp()
print(a)

3
2

In [4]: # local and global -> local does not have but global has

a=2 #global variable

def temp():
print(a)

temp()
print(a)

2
2

In [5]: # local and global -> editing global


# Local can only access the global but cannot modify it, can see it but cannot edit it

a=2 #global variable

def temp():
#local var
a+=1
print(a)

temp()
print(a)

---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
Cell In[5], line 8
5 a+=1
6 print(a)
----> 8 temp()
9 print(a)

Cell In[5], line 5, in temp()


3 def temp():
4 #local var
----> 5 a+=1
6 print(a)

UnboundLocalError: cannot access local variable 'a' where it is not associated with a value

In [6]: # Global Keyword

a=2 #global variable

def temp():
global a
a+=1
print(a)

temp()
print(a)

3
3

In Python, the global keyword is used to declare that a variable inside a function refers to a globally defined variable outside the function's scope. By default, when you assign a value to a variable within a function, Python treats it as a local variable. If you want to modify a global
variable inside a function, you need to declare it as global .

How global Works

When you use global variable_name inside a function:

1. Python searches for variable_name in the global namespace instead of creating a new local variable.
2. Changes to variable_name within the function will affect the global variable outside the function.

When to Use global

Use global when you need to modify a global variable inside a function.
Avoid using global excessively, as it can make code harder to read and maintain by tightly coupling functions with global state.

Limitations
global cannot be used to declare variables outside of all functions in the script or module scope.
It only affects variable references within the function where it's declared, not across other modules.

In [7]: # local and global -> global created inside local

def temp():
global a
a=1
print(a)

temp()
print(a)

1
1

In [13]: # local and global -> function parameter is local

def temp(z):
print(z)

a=5
temp(5)
print(a)
print(z)

5
5
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[13], line 7
5 temp(5)
6 print(a)
----> 7 print(z)

NameError: name 'z' is not defined

Built-in Scope
The built-in scope in Python is the outermost scope where Python's built-in functions, constants, and exceptions reside. This includes functions like print() , len() , sum() , and constants such as True , False , and None . The built-in scope is part of Python's standard library,
and the objects defined in it are available globally in any Python script or module.

How the Built-in Scope Works


1. Accessibility: Objects in the built-in scope are accessible throughout a Python program without needing to import or define them in each file. For example, you can use print() or len() anywhere in your code without any specific import statement.

2. Immutability: Since the built-in scope is defined when Python starts up, objects in this scope are essentially immutable for practical purposes, meaning they should not (and usually cannot) be redefined. However, technically, if you assign True = False , Python will allow it, but
this will cause severe bugs and break the program's logic.

3. Namespace Hierarchy: Python resolves variable names by looking up the namespace hierarchy: local → enclosing → global → built-in. If a name isn’t found in the local, enclosing, or global scope, Python finally checks the built-in scope.

In [14]: # Builtin scope

print("hello")

hello

In [15]: # Accessing All Built-ins

import builtins
print(dir(builtins))

['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BaseExceptionGroup', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'Conn
ectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EncodingWarning', 'EnvironmentError', 'Exception', 'ExceptionGroup', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'Fu
tureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError',
'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarnin
g', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'Unic
odeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '__IPYTHON__', '__build_class__', '__debug__', '__doc__', '__import__', '__loader_
_', '__name__', '__package__', '__spec__', 'abs', 'aiter', 'all', 'anext', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'd
ict', 'dir', 'display', 'divmod', 'enumerate', 'eval', 'exec', 'execfile', 'filter', 'float', 'format', 'frozenset', 'get_ipython', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclas
s', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'range', 'repr', 'reversed', 'round', 'runfile', 'set', 'setattr', 'slice', 'sorte
d', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

Modifying Built-in Scope (Not Recommended)


In [1]: # Don't do this!

len = 5
print(len([1, 2, 3])) # This will raise a TypeError because `len` is now an integer, not a function

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[1], line 5
1 ### Modifying Built-in Scope (Not Recommended)
2
3 # Don't do this!
4 len = 5
----> 5 print(len([1, 2, 3]))

TypeError: 'int' object is not callable

In [22]: # Avoid naming your variables after built-in functions or constants to prevent accidental overrides.

L=[1,2,3]
max(L)

def max():
print("hello")

max(L)

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[22], line 4
1 #rename built-ins
3 L=[1,2,3]
----> 4 max(L)
6 def max():
7 print("hello")

TypeError: max() takes 0 positional arguments but 1 was given

Enclosing Scope
The enclosing scope in Python refers to the scope of any outer, or "enclosing," function within which a nested (inner) function is defined. This is sometimes also called the "nonlocal" scope. When an inner function tries to access a variable that isn’t defined locally, Python will check the
enclosing function’s scope to resolve the variable before moving on to the global or built-in scopes.

How the Enclosing Scope Works


1. Nested Functions: Enclosing scopes are created by nested functions. If you define a function within another function, the outer function's scope becomes the enclosing scope for the inner function.
2. Name Resolution: Python resolves variable names by following this order: local → enclosing → global → built-in.
3. Nonlocal Keyword: If you want to modify a variable from the enclosing scope inside the inner function, you must use the nonlocal keyword. Otherwise, assigning to a variable in the inner function will create a new local variable, not modifying the one in the enclosing scope.

In [30]: # enclosing scope

def outer():
def inner():
print(a)
inner()
print("outer function")

outer()

print("main program")

1
outer function
main program

In [29]: # nonlocal keyword

def outer():

def inner():

print(a)
inner()
print("outer")

#b=1
outer()
print("main program")

---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[29], line 12
9 print("outer")
11 #b=1
---> 12 outer()
13 print("main program")

Cell In[29], line 8, in outer()


5 def inner():
7 print(b)
----> 8 inner()
9 print("outer")

Cell In[29], line 7, in outer.<locals>.inner()


5 def inner():
----> 7 print(b)

NameError: name 'b' is not defined

Modifying Enclosing Scope Variables with nonlocal

Here, nonlocal allows inner_function to modify the message variable from outer_function . Without nonlocal , assigning a new value to message inside inner_function would create a new local variable named message without affecting the enclosing scope.

In [32]: # nonlocal keyword

def outer():
a=1
def inner():
nonlocal a
a+=1
print("inner",a)
inner()
print("outer",a)

#b=1
outer()
print("main program")

inner 2
outer 2
main program

You might also like