Everything in Python is an object.. This is the most common phrase you read when you enter the world of Python. All data types and functions that we use in Python are actually the objects of some bigger class. So when we initialize a variable (int, string or list etc.), we are actually creating an object of that class (int, string, list or whatever we initialize). Same is the case when we call a built-in function. This can be viewed as:
variable_name = object
So if all these things are object, this means there must be some attributes associated with Python objects. Identity (id), type and value, these 3 main attributes are associated with each python object. Understanding of these attributes is necessary to further move to concept of Mutable and Immutable.
Identity is the address of object in memory and is represented by a numerical value. Every object in Python has distinct location in memory (remember this line). id() is used to check the address of an oject in our program. To check if two objects in memory have same address, is operator is used. Let's try this.
# intializing 3 variables
alpha = 911
beta = 'Python'
charlie = alpha
#printing the id of variables
print('OUTPUT:')
print('id of alpha: ', id(alpha))
print('id of beta: ', id(beta))
print('id of cahrlie: ', id(charlie))
OUTPUT:
id of alpha: 2178192041360
id of beta: 2178152141128
id of cahrlie: 2178192041360
Here we can see that id of aplha and charlie are same, means both were referencing the same address in memory, which contains a value 911. We can test this too using is operator.
#using 'is' operator
alpha is charlie
True
#using 'is operator'
alpha is beta
False
Type, as name suggests, tells us what is the data type of variale that we have initialized. When we intialize a object variable, Python itself detects from which class it belongs. Type of object determines what operations can be performed on that object.
type() is used in Python to check the type of variables in Python. Let's check the our variables we initiliazed above.
# checking type of variables. type() tell from which class our variable belongs
print('OUTPUT:')
print('Type of alpha: ', type(alpha))
print('Type of beta: ', type(beta))
print('Type of charlie: ', type(charlie))
OUTPUT:
Type of alpha: <class 'int'>
Type of beta: <class 'str'>
Type of charlie: <class 'int'>
Look Python detected itself the type of variables. Output tells alpha and charlie belong to class of int/integer whilel beta belongs to str/string class.
Value is what value we assign to our object. Like we assigned a value 911 to variable alpha and charlie, and assigned Python to variable beta (let Python take the headache of their types).
Now we have understood the concept of id, type and value, we are ready to understand the concept of Mutable and Immutable objects.
As we are learning Python, we should be clear that all the objects in Python are either Mutable or Immutable. And they are pretty simple to understand.
: Objects whose value can be changed. : Objects whose value can NOT be changed once they are created.
Let's understand what these definitions mean. We'll use the three valriables, alpha beta and charlie, defined earlier.
First we will se how immuttable obejcts work. As alpha and charlie both are int and int is immutable type. We can not change the value of an immutable object.
#print value and id of alpha
print(alpha)
print('id of alpha: ', id(alpha))
911
id of alpha: 2178192041360
Now let's change value.
#changing value of alpha
alpha = alpha + 5
print(alpha)
916
Well Congratulations!! You just changed the value of an immutable object.
But WAIT!!
#print id of alpha
print('id: ', id(alpha))
id: 2178192041008
Look id(memory address) of alpha has been changed. So, you didn't changed the value of alpha actually. What you did is that you created a new int object whose value is 916 and it's named alpha.
Also we will see value of charlie because charlie and alpha were same as we did charlie = alpha.
#printing value and id of charlie
print('value: ', charlie)
print('id: ', id(charlie))
value: 911
id: 2178192041360
We can see value and id of charlie is not updated and it retained it's attributes.
That is how immutable data objects work.
Now we will examine working of mutable objects. Lets first define a mutable object, list.
#defining a list which is mutable
myList = [1,2,'Python',3]
myList_2 = myList
#printing value and id of myList
print('myList: ', myList)
print('id myList', id(myList))
print('myList_2: ', myList_2)
print('id myList_2 ', id(myList_2))
myList: [1, 2, 'Python', 3]
id myList 2178192129352
myList_2: [1, 2, 'Python', 3]
id myList_2 2178192129352
Now as list is mutable, we can change/update it's value inplace(on the same memory address) using Python's built-in function(s).
myList.append('awesome')
#printing value and id of myList
print('value: ', myList)
print('id ', id(myList))
value: [1, 2, 'Python', 3, 'awesome']
id 2178192129352
Value of myList is updated while retaining the place in memory. And if we see value of myList_2, it has been updated too, which didn't happen in case of immutable objects.
#printing value and id of myList_2
print('value: ', myList_2)
print('id ', id(myList_2))
value: [1, 2, 'Python', 3, 'awesome']
id 2178192129352
Now lets see an case of immutable data objects.
#defining a tuple
myTuple = ('Python', [1,2,3])
print(myTuple)
print('id:',id(myTuple))
('Python', [1, 2, 3])
id: 2178190987336
In myTuple, we have two values, one is string which is immutable and other is a list which is mutable. We have contained an immutable and a mutable object within an immutable object.
As we can change the value of a mutable object, we will do it and see what happens.
# taking value of list from tuple
t_list = myTuple[1]
print(t_list)
[1, 2, 3]
t_list.append('awesome')
print(t_list)
[1, 2, 3, 'awesome']
#printing value and id of myTuple
print(myTuple)
print('id: ', id(myTuple))
('Python', [1, 2, 3, 'awesome'])
id: 2178190987336
As you can see above as we updated the value of list, it also got updated inside the tuple. It doesn't mean tuple is mutable. Tuple is a container, an object which can contain other data objects and itself is an object. What we did is that we just updated the values of a mutable object (which we can surely do!) inside a tuple. If we want to change the value of tuple, for example, if we want another instead of a list on second index of tuple, Python will not let us do this because tuple is immutable. We can check this as well.
myTuple[1] = 5
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-18-e896a0a9affc> in <module>()
----> 1 myTuple[1] = 5
TypeError: 'tuple' object does not support item assignment
So we see, trying to change an immutable object gives us an error.
At the last, there is another thing needed to be clear about Python object. As I said earlier, every object in Python has distinct location in memory. But in some cases for immutable objects, we will see this statement is not ture.
# defining two variables
a = 5
b = 5
a is b
True
Output True suggests that a and b have same memory address while both of them are seaparate varibales. This is because of caching in Python. Python caches objects with small values (-5 to 256) and variables with same values are assigned to that object. Like in our example, as a and b have same value, that is why both are referencing to same object. Now if we increase the values of both variables, greater than 256, result will change.
# chaning values of a and b
a = 257
b = 257
a is b
False
Same is the case for string object. String variables with same value upto 20-25 characters are referenced to same address.
Remember that this caching concept is for immutable objects.
This is all from this tutorial. Hope you enjoyed and understood the tutorial. Kindly let me know about your suggestions at burhan.naeem2@gmail.com .