Everything is an object! Mutable, Immutable. Python3

Steffany Naranjo Vargas
5 min readSep 30, 2020

Python is a hight level programming, that is easy to read, easy to use and easy to maintain. Every variable in python holds an instance of an object. There are two types of objects in python Mutable and Immutable objects. Whenever an object is instantiated, it is assigned a unique object id. The type of the object is defined at the runtime and it can’t be changed afterwards. However, it is state can be changed if it is a mutable object.

Identity

In order to obtain the identity of an object, the built in function id(object) is used.

The id value of commonly used data types, such as string, integer, tuples etc. So you might find that multiple variables refer to the same object and have same id() value if their values are same.

Let’s check this out with an example.

# integers 
a = 10
b = 10
c = 11
d = 12
print(id(a))
print(id(b))
print(id(c))
print(id(d))

Output

4317900064 
4317900064
4317900096
4317900128

Let’s see a simple example of getting id() value for a custom object.

class Emp:     
a = 0

e1 = Emp()
e2 = Emp()
print(id(e1))
print(id(e2))

Output

4520251744
4520251856

Type

The type() function either returns the type of the object or returns a new type object based on the arguments passed. The type() function has two different forms:

type(object)
type(name, bases, dict)

Get type of an object

numbers_list = [1, 2]
print(type(numbers_list))

numbers_dict = {1: 'one', 2: 'two'}
print(type(numbers_dict))

class Foo:
a = 0

foo = Foo()
print(type(foo))

Output

<class 'dict'>
<class 'Foo'>
<class '__main__.Foo'>

Mutable and Immutable objects

The mutable data types in Python are list, dictionary, set and user-defined classes.

# lists are mutable
color = ["red", "blue", "green"]
print(color)
color[0] = "pink"
color[-1] = "orange"
print(color)

Output

['red', 'blue', 'green']
['pink', 'blue', 'orange']

Immutable Objects : These are of in-built types like int, float, bool, string, unicode, tuple. In simple words, an immutable object can’t be changed after it is created.

# Python code test tupletuple1 = (0, 1, 2, 3)tuple1[0] = 4print(tuple1)

Error

Traceback (most recent call last):
File "e0eaddff843a8695575daec34506f126.py", line 3, in
tuple1[0]=4
TypeError: 'tuple' object does not support item assignment

Another example is:

# Python test strings are immutablemessage = "Hello world"
message[0] = 'p'
print(message)

Error

Traceback (most recent call last):
File "/home/ff856d3c5411909530c4d328eeca165b.py", line 3, in
message[0] = 'p'
TypeError: 'str' object does not support item assignment

Why does it matter and how differently does Python treat mutable and immutable objects.

Mutable and immutable objects are handled differently in python. Immutable objects are quicker to access and are expensive to change because it involves the creation of a copy.
Whereas mutable objects are easy to change.

Use of mutable objects is recommended when there is a need to change the size or content of the object.

Exception : However, there is an exception in immutability as well. We know that tuple in python is immutable. But the tuple consists of a sequence of names with unchangeable bindings to objects.
Consider a tuple

tup = ([3, 4, 5], 'myname')

The tuple consists of a string and a list. Strings are immutable so we can’t change its value. But the contents of the list can change. The tuple itself isn’t mutable but contain items that are mutable.

As a rule of thumb, Generally Primitive-like types are probably immutable and Customized Container-like types are mostly mutable.

How arguments are passed to functions and what does that imply for mutable and immutable objects

Arguments are always passed to functions by reference in Python. The caller and the function code blocks share the same object or variable. When we change the value of a function argument inside the function code block scope, the value of that variable also changes inside the caller code block scope regardless of the name of the argument or variable. This concept behaves differently for both mutable and immutable arguments in Python.

In Python, integer, float, string and tuple are immutable objects. list, dict and set fall in the mutable object category. This means the value of integer, float, string or tuple is not changed in the calling block if their value is changed inside the function or method block but the value of list, dict or set object is changed. Consider the mutable and immutable as states of the function arguments in Python. Let’s discuss it in detail with examples in the following section.

Python setattr

The setattr function sets the value of the attribute of an object. The syntax of setattr is:

setattr(object, name, value)

The setattr() function takes three parameters:

  • object — object whose attribute has to be set
  • name — attribute name
  • value — value given to the attribute

In Python stattr works in the next way

class Person:
name = 'Steffany'

p = Person()
print('Before modification:', p.name)

# setting name to 'Gabriela'
setattr(p, 'name', 'Gabriela')

print('After modification:', p.name)

Output

Before modification: Steffany
After modification: Gabriela

Python getattr

The getattr() method returns the value of the named attribute of an object. If not found, it returns the default value provided to the function. The syntax for getattr is:

getattr(object, name[, default])

And the above syntax is:

object.name

getattr() method takes multiple parameters:

  • object — object whose named attribute’s value is to be returned
  • name — string that contains the attribute’s name
  • default (Optional) — value that is returned when the named attribute is not found

getattr() method returns:

  • value of the named attribute of the given object
  • default, if no named attribute is found
  • AttributeError exception, if named attribute is not found and default is not defined

In python getattr works like the next example

class Person:
age = 23
name = "Adam"

person = Person()
print('The age is:', getattr(person, "age"))
print('The age is:', person.age)

Output

The age is: 23
The age is: 23

Whit this functions we can write a function magic_string() that returns a string “Holberton” n times the number of the iteration

def magic_string():    
setattr(magic_string, "n", getattr(magic_string, "n", 0) + 1) return ("Holberton, " * getattr(magic_string, "n", 0))[:-2]

And we will get this output

--

--