Mutability and Objects in Python3
Launching Python3 propels you into a world that consists of objects, links among said objects, and methods that operate on them. The goal is to leave you better equipped to understand Python’s paradigm so you can comprehend its language.
In the object-oriented paradigm, a class
>>> # Example of instantiating an int object>>> a = 1>>> type(a)<class 'int'>
>>> string1 = "Hemant">>> type(string1)<class 'str'>
>>> # Demonstrating the use of a string method on the object "Hemant">>> string1.upper()'HEMANT'
The builtin function, type(), returns the class that the object belongs to.
Given that Python deals with values as objects, it’s helpful to understand how it works in a toy problem.
>>> a = 1>>> b = 1
The code above has 2 variable names that refer to the same value. In C, these variables would store the same value in different memory locations on the stack. However, remember that variable names are just tags that reference an object in memory. The point of this discussion is that a and b ultimately point to the same object ‘1’ in memory!
>>> a is bTrue>>> a == bTrue
Using the ‘is’ and ‘==’ operators on the variable names returns True in both instances. The former operator checks for whether the names refer to the same object. Variables in Python are names that reference objects created in memory. The latter operator tests for object value equality, which returns True because a and b point to the same value. The return value from the is operator can be substantiated using the id() function. This function returns a unique integer representing the memory address of the underlying object.
>>> id(a)10088288>>> id(b)10088288
The return value from id() is the same, meaning that a and b refer to the same object.
Mutable Objects
Objects can come in two flavors: Mutable and Immutable. On a basic level, the difference lies in the ability to be transformed. Mutable objects can be changed whereas immutable objects are frozen after instantiation. Take for example the list, modifying the list’s elements or the size of the list is permissible by the interpreter. Initializing the list with specific values and changing the list elements at a later time won’t cause any exceptions to be raised by the interpreter.
>>> my_list = [1, 2, 3]>>> my_list[2] = 5>>> my_list[1, 2, 5]
Immutable objects
Objects of this kind are not capable of being changed. At the time of instantiation, values that were placed in the object are frozen. Instantiating a generic string and subsequently attempting to modify the string is not possible with objects of this type.
>>> string1 = "Hemant">>> string1[2] = 'c'Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: 'str' object does not support item assignment>>> # This same traceback is seen when attempting to assign value in an immutable object like a tuple
Why does it matter and how does Python treat mutable vs immutable objects?
Mutability is significant because multiple names can be bound to specific objects in memory. Depending on the specific situation, having a mutable type would also affect all its references which can lead to issues. For example, strings couldn’t be used as keys in dictionaries if they were mutable. Immutable types give you the guarantee that modifications to the underlying object are not permissible.
How are arguments passed to functions and what does that imply for the mutability of objects?
Python functions are Call-By-Object-Reference, meaning the mutability of the object affects the function’s behavior. Types that are immutable are passed by value and don’t make any changes to the underlying object. Mutable objects are passed by reference so the modification of the underlying object is possible.
Python’s object oriented paradigm is interesting because it exhibits behavior that is inherently different compared to C. Variable names link to objects in memory so it’s possible to have multiple references to the same object. Mutability affects the behavior of the movement of data to and from functions.