Whatever is associated with a variable name has to be stored in the program's memory somewhere. An easy way to think of this, is that every byte of memory has an index-number. For simplicity's sake, lets imagine a simple computer, these index-numbers go from 0 (the first byte), upwards to however many bytes there are.

Say we have a sequence of 37 bytes, that a human might interpret as some words:

"The Owl and the Pussy-cat went to sea"

The computer is storing them in a contiguous block, starting at some index-position in memory. This index-position is most often called an "address". Obviously this address is absolutely just a number, the byte-number of the memory these letters are residing in.

@12000 The Owl and the Pussy-cat went to sea

So at address 12000 is a T, at 12001 an h, 12002 an e ... up to the last a at 12037.

I am labouring the point here because it's fundamental to every programming language. That 12000 is the "address" of this string. It's also a "reference" to it's location. For most intents and purposes an address is a pointer is a reference. Different languages have differing syntactic handling of these, but essentially they're the same thing - dealing with a block of data at a given number.

Python and Java try to hide this addressing as much as possible, where languages like C are quite happy to expose pointers for exactly what they are.

The take-away from this, is that an object reference is the number of where the data is stored in memory. (As is a pointer.)

Now, most programming languages distinguish between simple types: characters and numbers, and complex types: strings, lists and other compound-types. This is where the reference to an object makes a difference.

So when performing operations on simple types, they are independent, they each have their own memory for storage. Imagine the following sequence in python:

>>> a = 3
>>> b = a
>>> b
3
>>> b = 4
>>> b
4
>>> a
3      # <-- original has not changed

The variables a and b do not share the memory where their values are stored. But with a complex type:

>>> s = [ 1, 2, 3 ]
>>> t = s
>>> t
[1, 2, 3]
>>> t[1] = 8
>>> t
[1, 8, 3]
>>> s
[1, 8, 3]  # <-- original HAS changed

We assigned t to be s, but obviously in this case t is s - they share the same memory. Wait, what! Here we have found out that both s and t are a reference to the same object - they simply share (point to) the same address in memory.

One place Python differs from other languages is that it considers strings as a simple type, and these are independent, so they behave like numbers:

>>> j = 'Pussycat'
>>> k = j
>>> k
'Pussycat'
>>> k = 'Owl'
>>> j
'Pussycat'  # <-- Original has not changed

Whereas in C strings are definitely handled as complex types, and would behave like the Python list example.

The upshot of all this, is that when objects that are handled by reference are modified, all references-to this object "see" the change. So if the object is passed to a function that modifies it (i.e.: the content of memory holding the data is changed), the change is reflected outside that function too.

But if a simple type is changed, or passed to a function, it is copied to the function, so the changes are not seen in the original.

For example:

def fnA( my_list ):
    my_list.append( 'A' )

a_list = [ 'B' ]
fnA( a_list )
print( str( a_list ) )
['B', 'A']        # <-- a_list was changed inside the function

But:

def fnB( number ):
    number += 1

x = 3
fnB( x )
print( x )
3                # <-- x was NOT changed inside the function

So keeping in mind that the memory of "objects" that are used by reference is shared by all copies, and memory of simple types is not, it's fairly obvious that the two types operate differently.

Answer from Kingsley on Stack Overflow
Top answer
1 of 5
11

Whatever is associated with a variable name has to be stored in the program's memory somewhere. An easy way to think of this, is that every byte of memory has an index-number. For simplicity's sake, lets imagine a simple computer, these index-numbers go from 0 (the first byte), upwards to however many bytes there are.

Say we have a sequence of 37 bytes, that a human might interpret as some words:

"The Owl and the Pussy-cat went to sea"

The computer is storing them in a contiguous block, starting at some index-position in memory. This index-position is most often called an "address". Obviously this address is absolutely just a number, the byte-number of the memory these letters are residing in.

@12000 The Owl and the Pussy-cat went to sea

So at address 12000 is a T, at 12001 an h, 12002 an e ... up to the last a at 12037.

I am labouring the point here because it's fundamental to every programming language. That 12000 is the "address" of this string. It's also a "reference" to it's location. For most intents and purposes an address is a pointer is a reference. Different languages have differing syntactic handling of these, but essentially they're the same thing - dealing with a block of data at a given number.

Python and Java try to hide this addressing as much as possible, where languages like C are quite happy to expose pointers for exactly what they are.

The take-away from this, is that an object reference is the number of where the data is stored in memory. (As is a pointer.)

Now, most programming languages distinguish between simple types: characters and numbers, and complex types: strings, lists and other compound-types. This is where the reference to an object makes a difference.

So when performing operations on simple types, they are independent, they each have their own memory for storage. Imagine the following sequence in python:

>>> a = 3
>>> b = a
>>> b
3
>>> b = 4
>>> b
4
>>> a
3      # <-- original has not changed

The variables a and b do not share the memory where their values are stored. But with a complex type:

>>> s = [ 1, 2, 3 ]
>>> t = s
>>> t
[1, 2, 3]
>>> t[1] = 8
>>> t
[1, 8, 3]
>>> s
[1, 8, 3]  # <-- original HAS changed

We assigned t to be s, but obviously in this case t is s - they share the same memory. Wait, what! Here we have found out that both s and t are a reference to the same object - they simply share (point to) the same address in memory.

One place Python differs from other languages is that it considers strings as a simple type, and these are independent, so they behave like numbers:

>>> j = 'Pussycat'
>>> k = j
>>> k
'Pussycat'
>>> k = 'Owl'
>>> j
'Pussycat'  # <-- Original has not changed

Whereas in C strings are definitely handled as complex types, and would behave like the Python list example.

The upshot of all this, is that when objects that are handled by reference are modified, all references-to this object "see" the change. So if the object is passed to a function that modifies it (i.e.: the content of memory holding the data is changed), the change is reflected outside that function too.

But if a simple type is changed, or passed to a function, it is copied to the function, so the changes are not seen in the original.

For example:

def fnA( my_list ):
    my_list.append( 'A' )

a_list = [ 'B' ]
fnA( a_list )
print( str( a_list ) )
['B', 'A']        # <-- a_list was changed inside the function

But:

def fnB( number ):
    number += 1

x = 3
fnB( x )
print( x )
3                # <-- x was NOT changed inside the function

So keeping in mind that the memory of "objects" that are used by reference is shared by all copies, and memory of simple types is not, it's fairly obvious that the two types operate differently.

2 of 5
5

Objects are things. Generally, they're what you see on the right hand side of an equation.

Variable names (often just called "names") are references to the actual object. When a name is on the right hand side of an equation1, the object that it references is automatically looked up and used in the equation. The result of the expression on the right hand side is an object. The name on the left hand side of the equation becomes a reference to this (possibly new) object.

Note, you can have object references that aren't explicit names if you are working with container objects (like lists or dictionaries):

a = []  # the name a is a reference to a list.
a.append(12345)  # the container list holds a reference to an integer object

In a similar way, multiple names can refer to the same object:

a = []
b = a

We can demonstrate that they are the same object by looking at the id of a and b and noting that they are the same. Or, we can look at the "side-effects" of mutating the object referenced by a or b (if we mutate one, we mutate both because they reference the same object).

a.append(1)
print a, b  # look mom, both are [1]!

1More accurately, when a name is used in an expression

🌐
Python documentation
docs.python.org › 3 › reference › datamodel.html
3. Data model — Python 3.14.8 documentation
Types affect almost all aspects of object behavior. Even the importance of object identity is affected in some sense: for immutable types, operations that compute new values may actually return a reference to any existing object with the same type and value, while for mutable objects this is not allowed.
🌐
Robert Heaton
robertheaton.com › 2014 › 02 › 09 › pythons-pass-by-object-reference-as-explained-by-philip-k-dick
Is Python pass-by-reference or pass-by-value? | Robert Heaton
The two most widely known and easy to understand approaches to parameter passing amongst programming languages are pass-by-reference and pass-by-value.
🌐
freeCodeCamp
freecodecamp.org › news › how-passing-by-object-reference-works-in-python
How Passing by Object Reference Works in Python
March 26, 2026 - When you pass a variable to a function in Python, you're passing a reference to the object that variable points to, not a copy of the value, and not the variable itself.
🌐
Medium
medium.com › @officialyrohanrokade › simplified-pythons-reference-handling-understanding-object-referencing-deleting-references-and-ae4026a74d7b
Simplified Python’s Reference Handling: Understanding Object Referencing, Deleting References, and Shallow Copying vs. Deep Copying | by Rohan Rokade | Medium
December 8, 2023 - Assigning one object to the other doesn’t spawn a new object; it establishes another reference to the same object. Modifying attributes through one reference influences the shared object, impacting both references. Reference counts serve as a fundamental part of Python’s memory management.
🌐
Bite Code
bitecode.dev › bite code! › python variables, references and mutability
Python variables, references and mutability - Bite code!
September 19, 2023 - In Python, there is no "by value". Everything is "by reference". You can get a unique number that represents the object behind that reference using the id() function:
🌐
LabEx
labex.io › tutorials › python-how-to-understand-object-references-in-python-398254
How to understand object references in Python | LabEx
In Python, everything is an object, and when you work with objects, you're actually working with object references.
Find elsewhere
🌐
Python Tutorial
pythontutorial.net › home › advanced python › python references
Python References
March 27, 2025 - In Python, a variable is not a label of a value as you may think. Instead, A variable references an object that holds a value.
🌐
Real Python
realpython.com › videos › object-references
Object References (Video) – Real Python
So, at some point in the life cycle of the program, Python notices that there is this object, 300, that there’s no way of it being accessed anymore, so it just comes around and collects it and just removes it out of memory. 03:58 And that’s the end of the lifecycle of this specific object. 04:03 So, as a quick recap about object references, the important thing to remember is that everything is an object.
Published: December 10, 2019
🌐
Python
docs.python.org › 2.0 › ref › objects.html
3.1 Objects, values and types
In most cases, when we talk about the value of a container, we imply the values, not the identities of the contained objects; however, when we talk about the mutability of a container, only the identities of the immediately contained objects are implied. So, if an immutable container (like a tuple) contains a reference to a mutable object, its value changes if that mutable object is changed.
🌐
GeeksforGeeks
geeksforgeeks.org › python › shared-reference-in-python
Shared Reference in Python - GeeksforGeeks
July 27, 2026 - A shared reference occurs when multiple variables refer to the same object in memory. Instead of creating a new object during assignment, Python creates another reference to the existing object.
🌐
Medium
medium.com › geekculture › python-reference-e6458a9a0582
Python — Reference
August 9, 2022 - In Python, a variable is not a label of value like you may think. Instead, a reference in python means a different name for a memory location that has been associated.
🌐
Medium
medium.com › swlh › a-deep-dive-into-variables-in-python-8f55f69c3653
A Deep Dive Into Variable References in Python | The Startup
June 14, 2020 - Instead, Python creates a new reference to an object representing that value. For example, the line a = 1 assigns the value 1 to the variable a. Behind the scenes, Python creates a new reference for a to point at the object representing the value 1.
🌐
Codementor
codementor.io › community › variable references in python
Variable references in Python | Codementor
April 22, 2019 - For the first statement as we agreed above, an object in memory is initialized with value 1. A reference 'a' is added to it and the reference count of '1' increments. When Python executes the next statement b=1, since it is the same value (1), a new object is not initialized.
🌐
Useful
useful.codes › objects-and-references-in-python
Objects and References in Python | Useful Codes
In summary, understanding Objects and References in Python is critical for effective memory management. Python’s memory manager, reference counting, and the distinction between mutable and immutable objects all play vital roles in how objects are created, referenced, and ultimately destroyed.
🌐
Reddit
reddit.com › r/learnpython › how to store an object reference in a variable?
r/learnpython on Reddit: How to store an object reference in a variable?
October 19, 2022 -

Hi,

Is it possible to store the object reference instead of the value in a variable? Normally, when I do something like my_var = my_object, Python does a type conversion so that my_var becomes an str variable, leading to an attribute error like "str has no attribute ...". Is it possible to avoid that by storing the object reference itself?

🌐
Real Python
realpython.com › ref › glossary › reference-count
reference count | Python Glossary – Real Python
Every object in Python has an associated reference count, which keeps track of the number of references pointing to that object. When you create a new reference to an object, its reference count increases by one.