What is a Namespace and scope in Python?In a classroom full of students, there is a high possibility of at least two students having the same name. How do we refer to those students? We'll use the last name or surname that identifies each person uniquely. In the Python classroom of objects, there is a need for individual identity. With a huge number of objects, Python uses the concept of Namespaces to manage the names. In this tutorial, we'll learn what the word "Namespace" means and many more concepts, along with examples. An object in Python can be anything from a variable to a method. Python stores all the names of the objects in the form of a dictionary with names as keys and objects as values: Dict = {name1: obj1, name2: obj2…} Definition of a Namespace:A namespace in Python is the collection of objects defined along with the names they're defined within the form of a dictionary. Every name: object (key: value) pair in the namespace explains about one corresponding object. Python has a lot of built-in libraries and so a lot of built-in objects. To check all the built-in objects in Python:
Output: ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', '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', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
Python identifies the objects using the namespaces. How does it identify two objects with the same name? First, there are 3 types of Namespaces in Python:
As the names suggest:
Look at the following example:
Note that in a single namespace, there can't be two objects of the name type with the same name. There can be objects with the same name and types in different namespaces. An object can hence exist in more than one namespace simultaneously. Here comes another question:How does Python find out which object we refer to when objects with the same name exist in multiple namespaces? The answer lies in a concept called "The Scope". The scope of an object is the part of the program in which it has meaning. Based on where the object is defined and the parts where it is referenced, the interpreter determines the scope of the object. When we refer to an object in the program to find it, Python follows a rule called the LEGB Rule L: Local namespace E: Enclosing namespace G: Global namespace B: Built-in namespace Suppose we referred to a variable a:
Here are a few examples: Example1: Output: object Understanding:In the above program, we are referring to a inside the enclosed_function(). The namespaces:
The search will go like this:
Example 2: Output: Local object Understanding: We referred to a inside the enclosed_function() The namespaces:
The search goes like this: 1. L: Enclosed namespace: Found The interpreter prints the value of a in the enclosed namespace and doesn't search any further. Example 3: Output: enclosing Understanding: We referred to a inside the enclosed_function() The namespaces:
The search goes like this: L: Enclosed namespace: Not found E: Enclosing namespace: Found Example 4: Output: NameError: name 'a' is not defined Understanding: We referred to a inside the enclosing_function() The namespaces:
The search goes like this: L: Enclosing namespace: Not found E: No enclosing function G: Not found B: Not found Hence, NameError
Now that we learned about types of namespaces, here is a point to grab:
Accessing the namespaces: We already accessed the built-in namespace using the dir(__builtins__) earlier in the tutorial. We'll now learn how to access the global and local namespaces: The Global namespace: We can access the global namespace using a built-in function called globals() In interactive mode (cmd): Output: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': Understanding: 'a' : 'Global' Here, a is the name, and 'Global' is the object. We can also use the function in an IDE-> print(globals()) Here is another example: Output: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': Understanding: We created a function f() in which we defined a local variable b. When we called globals():
Depending on your application, the dictionary can have different names. As it is a dictionary, we can perform some operations like:
Local namespace: Like global() for the global namespace, there is a function locals() to access the local namespace. It should be called inside a function to get the function's namespace. If it is used outside the function, it will act like globals(). Here is an example: Output: {'b': 1, 'c': 2} 3 Some important points to grab:
Here is an example: Output: {'a': 3, 'b': 4} {'a': 5, 'b': 4} {'a': 3, 'b': 4, 'local': {...}} Understanding: In the above example, we created a function add(). Python creates a local namespace for the function add(). We stored the locals() dictionary in the local variable. We modified the local variable. Observe that the change is not reflected in the original local namespace, and the copy we created locally is added to the local namespace. Hence, we can't make changes to the original local namespace like we can to the global namespace. Modifications: We learned that two objects with the same name could exist in different scopes. Now, we'll see which arguments can be modified in which scopes and which can't be. Here are two important points:
Let us understand the first point with an example: Strings are immutable. We defined a string a in the global scope, and inside the function f(), we tried to modify the value of a. Hence, the value of a in the global scope is printed. Mutable objects: Lists are mutable. Hence, it is modified in the local scope. If we try to reassign a mutable object: When we reassign the value of a in the local scope, a new local object will be created as two objects of the same name can be stored in two different namespaces. Hence, when we refer to a in the global namespace, a in the global namespace is printed. Python never leaves us without a way. If we need to modify an immutable object in another scope:
1. global declaration: Suppose we want to modify a global object inside a function (local scope). To stop Python from creating a new local object, we can refer to the global object using the global reference: By the statement global a, we're telling the interpreter that any references to a inside the function are actually to the global object a. What if we refer to a global object that isn't even in the global namespace?Yes, Python creates the object and places it in the global namespace. 2. globals() function: Using this function, we can access the global namespace and update the object: 3. nonlocal declaration If we want to modify an object of the enclosing function inside the enclosed function, we can use the nonlocal declaration. Global declaration or function doesn't work here as the object we want to modify isn't in the global namespace but the namespace of the enclosing function. Here is an example:
End checklist:
Next TopicUpdate Pyspark Dataframe Metadata |