Behind The Scenes: Objects in Python

Behind The Scenes: Objects in Python

Introduction

Unlike my usual “Breakdown” blogs, this article is going to be covering a bit more of a general topic that can be applied to any Python program. We’re going to be exploring a bit of the invisible inner-workings of Python as a language and the concept of “everything is an object.”

Id and Type

The functions id() and type() are some very useful built in tools used to identify and compare objects. On a very basic level, id() accepts any object as an argument and returns the “identity” of an object, usually represented by a number. This identity is created when the object was made and cannot be changed. The function type(), on the other hand, returns the type of the object. For instance, if you create a variable and set it to a number like 25, that variable would have the type “int”. So, why are these useful? Well, the utility of type() is pretty apparent. It allows you to check if the type of an object is what you expected, for instance. To realize how useful id() is, we need to learn about this “identity” that all objects have. The identity of an object is entirely unique to that object. No other object in the program will have that same identity. This means that if variable a and variable b both return the same number when passed to id(), they are referencing the exact same object. Any change to one will affect the other.

No alt text provided for this image

Mutable Objects

Let’s talk about the ability to change objects. When exploring documentation for different types, you may have noticed the adjectives “mutable” and “immutable”. The basic definition of mutable is “having the ability to change”. This essentially means that after creating an object, you are free to change and modify it however you like so long as you have access to the object, of course. Some examples of mutable objects are lists, dicts, and sets. The example below shows how a list can be modified.

No alt text provided for this image

Immutable Objects

The basic definition of immutable is “not having the ability to change”. Exactly the opposite of mutable. This essentially means that after creating an object, you are unable to change or modify it even if you have access to the object. Some examples of immutable objects are ints, floats, bools, strings, and tuples. As you can see below, you’ll get an error when running a program that attempts to change an immutable object.

No alt text provided for this image

Why does it matter?

Now that we understand what they are, does it even matter? Well, aside from the obvious issue of errors when running a program, there are several things to keep note of when manipulating objects in python. One of the main mistakes that people tend to make is using the keyword “is” to compare objects when they should use “==”. The differences between the two are pretty simple: “==” compares the value of the objects (as defined by the object) and the other compares the aforementioned identity of the objects to see if they are the exact same object. People often get into this bad habit because doing things like the first example below will work due to the fact that the ints from -5 to 256 are sort of omnipresent objects. Objects for every integer from -5 to 256 will always exist with the same “identity” even while nothing refers to it. This is by design as these are the most commonly used numbers. These are defined by the macros NSMALLPOSINTS and NSMALLNEGINTS which are set to 256 and -5 respectively by default. Ints are immutable, so doing something like `a += 1` doesn’t change the object, it just changes which object the variable `a` refers to. You can see proof of this behavior in the second example below.

No alt text provided for this image
No alt text provided for this image

How are arguments passed to functions?

With all of this new knowledge, you’re bound to look at objects and variables very differently now. One of the first places you will start to see this behavior is when creating functions. Let’s look into how arguments are actually passed to functions. The technical term for Python’s method of calling functions is “Call-by-Object”. Essentially, every argument is “passed by reference” instead of “passed by value”, meaning that passing variable 'a' into func() will actually pass a reference to what 'a' is referencing. This has different behaviors depending on whether the object referenced is mutable or not. Just like the example previously with ints, if an object passed is immutable, changing anything about the variable inside the function will not affect the variable that was passed outside the function. If the object is mutable, you are able to affect the object outside the function like the example below. The simplest way to think about this is to treat everything as just simple assignments. Given a function foo(bar), if we pass variable a into it foo(a), we are basically just setting bar = a. All of the same rules apply as if we were just setting a variable equal to another.

Kelsie Merchant

Engineer - Physics and Machine Learning

4 年

Great post, Sean! I like that you break down the difference between "==" and "is" since there can be a lot of confusion initially about when to use one vs. the other, and they clearly show the user differences between mutable and immutable objects.

要查看或添加评论,请登录

社区洞察

其他会员也浏览了