If you’ve ever worked with lower level languages like C or C++, then you’ve probably heard of pointers. Pointers allow you to create great efficiency in parts of your code. They also cause confusion for beginners and can lead to various memory management bugs, even for experts. In this article, you’ll gain a better understanding of Python’s object model and learn why pointers in Python don’t really exist.
Everyone knows what an object is: a tangible thing that we can sense, feel, and manipulate. The earliest objects we interact with are typically baby toys. Wooden blocks, plastic shapes, and over-sized puzzle pieces are common first objects. Babies learn quickly that certain objects do certain things: bells ring, buttons are pressed, and levers are pulled.
The definition of an object in software development is not different. Software objects may not be tangible things that you can sense or feel, but they are models of something that can do certain things and have certain things done to them. Formally, an object is a collection of data and associated behaviors. So, knowing what an object is, what does it mean to be object-oriented? In the dictionary, oriented means directed toward. So object-oriented means functionally directed toward modeling objects. This is one of many techniques used for modeling complex systems. It is defined by describing a collection of interacting objects via their data and behavior.
When asked whether Python function calling model is “call-by-value” or “call-by-reference”, the correct answer is: neither.
What we commonly refer to as “variables” in Python are more properly called names. Likewise, “assignment” is really the binding of a name to an object. Each binding has a scope that defines its visibility, usually the block in which the name originates.
So, Python has name binding. it is the association between a name and an object (value). So in Python, we attach a name to an object. We can do this using the equal operator (=).
>>> x = 1
For example, the last code binds the name
x to the object
1 (an integer whose value is 1). After this assignment, the state of the Python interpreter is:
x ---> 1
Now, look what happens when we do this:
>>> x = 1
>>> y = 2
>>> z = x
Python creates a name
y and an object
2 and binds
2 and bind the name
z to the object bound to the name
x . Finally we could see as:
x ---> 1 <--- z
y ---> 2
It has 3 names and 2 objects.
Python created a name
z and bound it to the object
1, the object bound to
x. Note that Python didn’t create or copy the object
1, it only introduced a new name for that object. So both
z are bound to the object
Now, let’s see something that will blow your mind. Here is a example with a list:
> > > a = [1, 2, 3]
> > > b = a
This also is represented like this:
a ---> [1, 2, 3] <--- b
It has 2 names:
b and 1 object:
[1, 2, 3]. Ok, see the magic in this case:
> > > a.append(4)
> > > a
> > > [1, 2, 3, 4]
> > > b
> > > [1, 2, 3, 4]
a.append(4) doesn’t bind a name, it simply modifies (mutates) an object. It modifies
[1, 2, 3], the object bound to the name
a. The names
b are still bound to the same object, but that object has been modified.
Those examples brings us to an important point. There are actually two kinds of objects in Python. A mutable object that exhibits varying behavior. Python’s lists are an example of mutable objects. An immutable object does not exhibit varying behavior. The value of immutable objects can not be modified after they are created. They can be used to compute the values of new objects.
This is just the beginning. Be aware of the update of this articule!