Python is an object, even
Objects can be divided in two major sections:
mutable, but what are the differences between these two fancy terms?
In this post I’m going to show you the differences between
mutable by diving into
Python objects and knowing them well enough.
Everything is an object
To prove that everything is an object in
Python, go ahead and run the following snippet:
print( type(1) ) # Output: <class 'int'> print ( type(1.2) ) # Output: <class 'float'> print( type("Hello") ) # Output: <class 'str'>
This snippet shows us that
1 is a class of type
1.2 is a class of type
"Hello" is a class of type
Try the other types like boolean, and you’ll get the same result.
Pythonbuilt-in function in which it accepts a single parameter as an object and it returns the type of this object.
When we instantiate an object,
Python allocates a memory address for it and gives it a unique id at the runtime, and once it’s set it can never change.
By using the
id() function we can retrieve the object id at the runtime:
a = "Hello" print( id(a) ) # Output: a random number
Just remember that the object id is the location of the object in the memory.
immutable objects by an example:
h1 = "Hello" h2 = "Hello" print( id(h1) ) # Output: random number like: 4545012936 print( id(h2) ) # as same id(1)
As you see here, both
h2 have the same id, but why? It’s because they are using the same object location.
"Hello World" is defined, it’ll get its own unique id and whenever we use the same string
"Hello World" over and over,
Python will only allocate one address in memory for it:
So, regardless of how many times we define the
"Hello World" string, we’ll get exactly the same object id.
Let’s dig a bit deeper and examine the location of the
"Hello World" string:
h1 = "Hello World" h2 = "Hello World" print( id(h1) ) # Output: 4368067376 (random number) print( id(h2) ) # Output: same as id(h1) print( id("Hello World") ) # Output: same as h1 and h2
"Hello World" has exactly the same id as
immutable, which means their values cannot be change at runtime, rather using the same object id over and over.
Let’s take another example:
h1 += ", I love Python" print(h1) # Output: Hello World, I love Python
It seems like we are appending a stirng into
h1, in fact we are not changing the object that which
h1 referencing to, instead, we are creating a new object with a value of
"Hello World, I love Python":
Behind the scenes,
Python creates and manages all the objects for us, so
"Hello World" is an object by itself as well as
"Hello World, I love Python".
Python will automatically get rid of
"Hello World" by using its garbage collector, because it’s no longer needed.
Fair enough, now it’s the time to talk about the assignment operator.
The assignment operator (
=) binds an object to a name, it does not copy any values, for example
name = "Ahmad" means it binds the
name to the object
"Ahmad" has its own unique id, this unique id won’t be changed during runtime:
name = "Ahmad" name1 = "Ahmad" name2 = "Ahmad" # All these statements print the same value print( id(name) ) print( id(name1) ) print( id(name2) ) print( id(name3) )
All the data types in
Hold a sec, where are the variables here? why didn’t I mention the term variable?
Cite: Python Apprentice by Robert Smallshire and Austin Bingham (https://leanpub.com/python-apprentice) (Chapter 4 – Built-in types and the object model).
Pythondoesn’t really have variables in the metaphorical sense of a box holding a value. It only has named references to objects, and these references behave more like labels which allow us to retrieve objects.
So far, we discussed the
immutable objects, now time to discuss the
mutable, the value can be changed during runtime without affecting the object id, so the object id (which is the memory address) remains intact:
mutable by an an example where we append a new item into a list:
s1 = [1, 2, 3, 4] s2 = s1 s2.append(5) print(s1) # Output: [1, 2, 3, 4, 5]
You might ask why
s1 returns the whole list? shouldn’t it return list from
4 instead of
No, that because any changes we make to either
s2 will affects the object reference:
So, by changing
s2 we are changing the reference itself, and by doing so, both
s2 will be affected, since they are referencing the same object:
In contrast with
mutable objects will always have different
ids at runtime, let’s take a look at another example:
s1 = [1, 2, 3, 4] s2 = [1, 2, 3, 4] # s1 and s1 have different reference ids print( id(s1) ) print( id(s2) )
That’s all about
Equality of value vs equality of identity
Let’s dig a bit deeper into
is and see the differences between these two operators.
is tests whether two references refer to the same object, in other words it tests the identity equality:
a = "Hello" b = "Hello" print( a is b ) # Output: True
immutable hence its value will never change.
If you are coming from
isis equal to
In other side, the
== tests the value and it does not care about the object id at all:
s1 = [1, 2, 3, 4] s2 = [1, 2, 3, 4] print( s1 is s2 ) # Output: False print( s1 == s2 ) # Output: True
Since list is an mutable object, it gets a new id each time we create one, so of course s1 is s2 gives us False because they are using different ids while s1 == s2 gives us True because their values are identical.
We discussed both
mutable objects by using a bunch of examples, just a recap of what we’ve learnt:
- All objects in Python are immutable except
id()function is used to reterive the object identifier in the memory.
type()function is used to get the data type of a given object.
is()tests the quality of two object identifier.
==tests the value of two objects.