Skip to main content

Command Palette

Search for a command to run...

Python Objects Have an Identity Card, and It Changed How I Think About Variables

Updated
6 min readView as Markdown
Python Objects Have an Identity Card, and It Changed How I Think About Variables
D

A dedicated Computer Engineering graduate from SCET. Throughout my academic journey, I navigated the dynamic landscape of education during the challenging Covid era, which instilled in me resilience and adaptability. My experience in the field of Data Engineering spans across Transact SQL, MS SQL Server, Agile Methodologies, and a foundational understanding of Azure Data Factory and various cloud services. These experiences have not only honed my technical acumen but also reinforced my capacity to thrive in diverse and evolving environments.

My current pursuits reflect a keen interest in expanding my knowledge in both DevOps and Cloud Engineering. Alongside these technical endeavors, I'm fervently learning Full Stack Web Development from the ground up, eager to explore the intricate interplay of front-end and back-end systems.

Embracing a holistic approach to problem-solving, I'm delving into the intricacies of System Design, striving to develop comprehensive and efficient solutions within the IT industry. Building on approximately 6 months to 1-year of hands-on industry experience, I'm driven to continuously enhance my skill set, contributing meaningfully to the technological landscape.

Beyond the realms of technology, I find solace in capturing the ephemeral beauty of sunsets through photography, letting the time freeze those breathtaking moments. Music is my constant companion, offering relaxation and inspiration. As an avid cricket enthusiast, the game brings camaraderie and excitement.

I'm always open to connecting with fellow professionals, learning from shared experiences, and contributing to the ever-evolving tech sphere. Let's connect and explore the limitless possibilities together!

I'll be honest, this is the post where Python stopped feeling like "just typing commands" and started feeling like there's actual machinery running underneath. It's about a concept called mutability, and it trips up almost everyone the first time, including me.

Here's the thing that finally made it click: in Python, literally everything is an object. Not just the lists and dictionaries you'd expect, but numbers, strings, booleans, all of it. And every single object carries three things around with it, whether you asked for them or not. Once I understood those three things, mutable and immutable stopped being abstract vocabulary and started being something I could actually picture in memory.

Term check: object In plain English, an object is just a thing that exists in memory while your program runs. Think of it like a labeled box sitting on a shelf. The label is what type of box it is, and inside is whatever value you put there.

The three things every object carries

Every object in Python has:

  1. An identity - a unique address in memory, basically its own ID number. This never changes for the lifetime of that object.

  2. A type - what kind of thing it is (int, str, set, and so on). This also never changes.

  3. A value - what's actually stored inside. This is the only one of the three that might change, and only for certain types.

That third point is exactly where mutability comes in.

Term check: identity This is a unique number Python assigns to every object when it's created, kind of like a serial number. You can check it yourself using the built-in id() function. Two objects with the same identity are literally the same object in memory, not just two objects that happen to look equal.

Mutable vs immutable, the part everyone gets backwards

Term check: mutable and immutable Mutable means changeable. Immutable means it cannot be changed. The trap is that most beginners try to figure out which one something is by watching whether the value looks different after some code runs. That's the wrong signal. The right signal is whether the identity stays the same.

I want to repeat that because it's the whole point of this post: never judge mutability by the value. Always judge it by the identity. If the identity stays the same after you "change" something, it's genuinely mutable. If the identity changes, what actually happened is Python quietly created a brand new object and pointed your variable at that instead.

Watching it happen with a number

Let's start with something that feels mutable but isn't. Numbers in Python are immutable.

sugar_amount = 2
print(f"initial sugar: {sugar_amount}")
print(f"id of sugar_amount: {id(sugar_amount)}")

sugar_amount = 12
print(f"updated sugar: {sugar_amount}")
print(f"id of sugar_amount now: {id(sugar_amount)}")

If I run this, the value obviously changes from 2 to 12. But if I check the id() before and after, the identity is different too. That's the giveaway. Python didn't reach into the box labeled sugar_amount and swap out what's inside. It created a completely new object holding 12, and just pointed sugar_amount at that new object. The old object holding 2 is still sitting in memory somewhere, untouched, just no longer referenced by anything.

Here's roughly what that looks like:

The variable is just an arrow. The reassignment moved the arrow. It didn't touch the box.

Now watching it happen with a set

Sets behave completely differently, and this is where the contrast actually teaches you something.

Term check: set A set is a data type that holds a collection of values, kind of like a list, except it doesn't keep duplicates and doesn't preserve order. You create one with curly braces or the set() function, and you add to it with .add().

spice_mix = set()
print(f"initial spice_mix: {spice_mix}")
print(f"id of spice_mix: {id(spice_mix)}")

spice_mix.add("clove")
spice_mix.add("ginger")
spice_mix.add("cardamom")

print(f"spice_mix after adding items: {spice_mix}")
print(f"id of spice_mix after adding items: {id(spice_mix)}")

I ran this expecting the id to change like it did with the number, since the set clearly looks different now, it went from empty to holding three items. But the id stays exactly the same the whole time. spice_mix is still pointing at the same object in memory. Python didn't create a new set every time I called .add(). It reached into the existing box and changed what's inside it directly.

That's mutability in action. The identity didn't move. The contents did.

Why this actually matters, not just as trivia

This isn't just a fun fact for interviews. It explains real behavior you'll run into constantly once you start passing variables into functions or storing them in other data structures.

If you hand a mutable object (like a set or a list) to a function and that function modifies it, the original object outside the function changes too, because there was only ever one object the whole time, just multiple names pointing at it. Immutable objects don't have this surprise, because "changing" one always means creating a new one somewhere else.

This is a preview of a headache called aliasing that I'll get into properly once we're deeper into lists and dictionaries, but the mutable/immutable foundation is what makes that topic make sense later.

Common mistakes

  • Checking whether something is mutable by comparing values before and after, instead of comparing id(). The value can look the same or different in ways that mislead you either way.

  • Assuming all "collection-looking" types behave the same. Strings look like they hold a sequence of characters similar to a list, but strings are immutable while lists are mutable. Type matters more than appearance.

  • Forgetting that reassigning a variable (sugar_amount = 12) is not the same operation as mutating an object in place (spice_mix.add(...)). They look similar on the surface but do very different things in memory.

  • Assuming the old object disappears immediately once nothing points to it anymore. It does eventually get cleaned up, but that's a separate topic (garbage collection), not something you need to manage yourself.

Quick recap

  • Every object in Python has an identity, a type, and a value.

  • Identity is a unique, unchanging reference you can check with id().

  • Mutable means the value inside an object can change while the identity stays the same. Immutable means any "change" actually creates a new object with a new identity.

  • Numbers, strings, booleans, and tuples are immutable. Sets, lists, and dictionaries are mutable.

  • Always verify mutability using identity, never using the value alone.

What's next

Now that identity and mutability are out of the way, the next post moves into Python's core data structures properly, starting with lists, since a lot of what makes lists behave the way they do traces straight back to what we just covered here.

Bite-Sized Python: Zero to Modular Code

Part 16 of 16

Learning to code or pivoting into modern software development can feel like wading through an ocean of tutorials. In this series, I document my hands-on journey through Python, breaking down every core concept into plain-English explanations, visual mental models, and ready-to-use code snippets. Whether you are writing your first print() statement or learning how to structure production-ready modular applications, follow along as we build our skills one post at a time.

Start from the beginning

Hello World: Setting the Stage for My Python Learning Series

I Wrote My First Python Program. Here's Everything It Took to Get There. Every time I scroll through job postings lately, artificial intelligence shows up somewhere in almost all of them. Companies ac

More from this blog

The Accidental Techie: Darshan Joshi

20 posts

Code creator by day, deep thinker by night✨ weaving bytes and pondering life's algorithms❤

A dedicated Computer Engineering graduate from SCET. Throughout my academic journey, I navigated the dynamic landscape of education during the challenging Covid era, which instilled in me resilience and adaptability. My experience in the field of Data Engineering spans across Transact SQL, MS SQL Server, Agile Methodologies, and a foundational understanding of Azure Data Factory and various cloud services. These experiences have not only honed my technical acumen but also reinforced my capacity to thrive in diverse and evolving environments.

My current pursuits reflect a keen interest in expanding my knowledge in both DevOps and Cloud Engineering. Alongside these technical endeavors, I'm fervently learning Full Stack Web Development from the ground up, eager to explore the intricate interplay of front-end and back-end systems.

Embracing a holistic approach to problem-solving, I'm delving into the intricacies of System Design, striving to develop comprehensive and efficient solutions within the IT industry. Building on approximately 6 months to 1-year of hands-on industry experience, I'm driven to continuously enhance my skill set, contributing meaningfully to the technological landscape.

Beyond the realms of technology, I find solace in capturing the ephemeral beauty of sunsets through photography, letting the time freeze those breathtaking moments. Music is my constant companion, offering relaxation and inspiration. As an avid cricket enthusiast, the game brings camaraderie and excitement.

I'm always open to connecting with fellow professionals, learning from shared experiences, and contributing to the ever-evolving tech sphere. Let's connect and explore the limitless possibilities together!