Python3: Mutable, Immutable… everything is object!

Jacob Ide
4 min readMay 27, 2020
“Everything is an Object” is Python’s corollary to Linux’s “Everything is a File”.

Introduction

Everything in Python, from lists to Modules is an object. Each of these objects conforms to a class, with classes themselves being objects with classes as well. And all of them, classes and objects have specific attributes and methods. Still confused? Well, allow me to explain borrowing from a totally not at-all-pretentious source: Platonic Metaphysics.

In Plato’s view of the world, any given object, a bee, a bus or a blog, is ultimately only a shadow of the perfect form of bee-ness, bus-ness, or blog-ness. All of these instances may have their instance-specific attributes (like name, location, etc.) but they share in the the divine Form that they instantiate. While much ink has spilled throughout the history of philosophy arguing Plato’s points, it can be used to understand the organizational relationship of objects and classes in Python.

Unlike the immutable Platonic forms, Python allows us to play Zeus and create our own Platonic Forms by declaring a class.

class Bee:
def __init__(self, name):
self.name = name

Plato or Zeus might be disappointed in the paucity of information contained in this class, but to keep our code samples short, I’ll just use it to assign the bee a name. Once defined, I might declare an instance of a bee named Melissa.

>>>Bee("Melissa")

No matter how many bees I instantiate, every Bee in the swarm will share in the class Bee as we in our divine wisdom have defined. The same can be said of any object instances we create with Python’s predefined classes (List, Tuple, etc.)

id() and type()

The sweet Melissa we conjured above has attributes beyond its name that we can access despite not having defined them in the class itself. Why? Because Melissa is an object that means that she shares in the Pythonic form of object-ness. Said less opaquely, all objects have a unique integer id that persists as long as the object exists, and, as they have a class, they have a type.

>>> id("Melissa")
139687672095384
>>> Melissa = Bee("Melissa")
>>> type(Melissa)
<class '__main__.Bee'>

Mutable Objects

Mutable objects are those objects who’s values can change without their id having to be reassigned. List, dict, set and occasionally tuple are mutable. for example:

>>> a  = [1, 2, 3]
>>>id(a)
140446156591752
>>> a[0] = 9
>>> a
[9, 2, 3]
>>>id(a)
140446156591752

Under what circumstances is a tuple mutable? Only when the tuple contains an element that IS mutable for example:

>>> a  = ([1, 2, 3], 7)
>>> a[0][0] = 9
>>> a
([9, 2, 3], 7)

Immutable Objects

Immutable objects are those objects that can’t be changed without changing their id. int, float, bool, string, unicode, tuple are all immutable. If a user tries to change an immutable object, they will get the following output.

>>> t = (1, 2, 3)
>>> t[4] = 4
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

An immutable object is useful if you want to ensure that the data is not changed when passed to a function.

This leaves a final interesting point to explore: What happens when two variables have the same immutable value?

>>> h1 = "holberton"
>>> id(h1)
140446149557936
>>> h2 = "holberton"
>>> id(h2)
140446149557936

Why does it matter?

Why is this? Because both h1 and h2 are aliased to the same object(“holberton”). It’s part of the special memory management mojo of Python. It uses less memory addresses by having two variables point to the same object in memory. It matters because of how Python handles objects passed to functions.

How Arguments are Passed to Functions

The final element to be explored is how this works with objects passed to functions. When an mutable object is passed to a function it is passed by reference, that is, by the id that is aliased to the variable that is passed. This means that the function can affect the value of the object.

On the other hand, if an immutable type is passed, it is passed by value. That means that any changes made to that value do not affect the memory space referenced by the immutable object.

--

--