Everything is an object in Python

Source: Cafepy

Everything is an object in Python, but what does that mean?

Introduction

What makes the Python programming language different from low-level languages such as C? Python is an Object Oriented Programming (OOP) language — what does that mean? It means the Python programming language consists of objects, which allows the user to have their own methods and attributes without having to re-create them each time. Python is built off of a data structure called the PyObject, which is what all the data types inherit from — hence why the language consists of objects.

What is an id and type?

What are id and types in Python? Ids and Types are objects — remember that Python is made up of objects! An id “returns the identity of an object” and each one is “unique and constant” for the object as long as you use it. For example:

# Declaring two string objects:
>>> obj1 = "Hi"
>>> obj2 = "Guillaume"
# Getting their ids:
>>> id(obj1)
139725014564344
>>> id(obj2)
139725014575280

As you can see, obj1 and obj2 each have their own unique ids. Ok, now what happens if I assign two objects to point to the same thing like the below:

>>> obj3 = "Guillaume"
>>> obj4 = "Guillaume"

What would happen if I ask for the id of both? Would they be the same or different?

>>> id(obj3)
139725014575280
>>> id(obj4)
139725014575280

They are the same, but why? When two objects are referring to the same value, this is known as an alias. However, what happens if the objects are mutable? We’ll talk about that in the next section, but first, what are types?

Types are objects, again! Type in Python is used to “return the type of an object” and its “return value is a type object and generally the same object as returned by object.__class__. So, if you wanted to find out what type is your variable, you can do this:

# Declaring an object named obj1:
>>> obj1 = "Julien"
# Finding its type:
>>> type(obj1)
<class 'str'>

Mutable Objects

What are mutable objects? Mutable objects are objects whose values can change — examples of mutable objects are lists, dict, set, byte array.

You might think that strings are mutable objects, but what happens if you concatenate the string with another string?

>>> str1 = "Julien might win at Starcraft"
>>> str2 = " or he might lose."
>>> str1 += str2
>>> print(str1)
Julien might win at Starcraft or he might lose.

A third string is created when you concatenate the two strings, but what if the strings are the same? If they are the same, in memory, a pointer will point to the spot. For example, using id:

# Assigning two objects to the same string
>>> a = "b"
>>> b = "b"
>>> id(a), id(b)
(139873424855424, 139873424855424)
# Both strings have the same id
# Adding third object 'c'
>>> c = "c"
>>> id(c)
139873424786912
>>> a += c
>>> print(a)
bc
>>> id(a)
139873423703824

As you can see, a has a new id after the two strings are concatenated.

Immutable Objects

What about immutable objects? Immutable objects consists of number, string, tuple, frozen set, and bytes. These are objects that can’t be manipulated; for example:

 # Declaring a tuple object:
>>> a = (1, )
>>> a.append(3)
# Getting an error when I try to append a new number to the tuple
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'

I can’t add or change the original tuple, but I can re-assign a to a new tuple:

>>> a = (2, )
>>> print(a)
(2,)
>>>

However, for tuples and frozen sets, even though they are immutable objects, Python handles them the same way as mutable since they may contain mutable objects.

Preallocation in Python

In Python, upon startup, Python3 keeps an array of integer objects, from -5 to 256. For example, for the int object, marcos called NSMALLPOSINTS and NSMALLNEGINTS are used:

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS 257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS 5
#endif
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
/* References to small integers are saved in this array so that they
can be shared.
The integers that are saved are those in the range
-NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
#endif
#ifdef COUNT_ALLOCS
Py_ssize_t quick_int_allocs;
Py_ssize_t quick_neg_int_allocs;
#endif

What does this mean? This means that when you create an int from the range of -5 and 256, you are actually referencing to the existing object.

Assignment vs Referencing

What does assignment and referencing mean in Python? In Python, it uses something called “Call by Object Reference”, for example:

If you pass immutable objects as arguments, they are passed by value since they can not be changed. However, if you passed a mutable object argument, you are passing the object as a reference because the objects can be changed. For example, if you pass a list to a function, lists can be changed since they are mutable; “if a new list is created, the old list will not be affected”.

References

http://www.python-course.eu/python3_passing_arguments.php

Show your support

Clapping shows how much you appreciated K.Wong’s story.