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
It is understood that these resources are freed when the object is garbage-collected, but since garbage collection is not guaranteed to happen, such objects also provide an explicit way to release the external resource, usually a close() method. Programs are strongly recommended to explicitly close such objects. The try…finally statement and the with statement provide convenient ways to do this. Some objects contain references to other objects; these are called containers.
🌐
Runestone Academy
runestone.academy › ns › books › published › fopp › TransformingSequences › ObjectsandReferences.html
9.4. Objects and References — Foundations of Python Programming
The answer is True. This tells us that both a and b refer to the same object, and that it is the second of the two reference diagrams that describes the relationship. Python assigns every object a unique id and when we ask a is b what python is really doing is checking to see if id(a) == id(b).
🌐
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. In other words, variables are references. The following example assigns a number with the value of 100 to a variable:
🌐
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 - Python employs a reference-based memory management system. Deleting references doesn’t immediately remove objects from memory; it decrements their reference counts. Assigning one object to the other doesn’t spawn a new object; it establishes another reference to the same object.
🌐
Runestone Academy
runestone.academy › ns › books › published › thinkcspy › Lists › ObjectsandReferences.html
10.10. Objects and References — How to Think like a Computer Scientist: Interactive Edition
In other words, a list is a collection of references to objects. Interestingly, even though a and b are two different lists (two different collections of references), the integer object 81 is shared by both. Like strings, integers are also immutable so Python optimizes and lets everyone share the same object for some commonly used small integers.
🌐
LabEx
labex.io › tutorials › python-how-to-understand-object-references-in-python-398254
How to understand object references in Python | LabEx
When you create an object in Python, the interpreter allocates memory for that object and returns a reference to it.
🌐
Real Python
realpython.com › videos › object-references
Object References (Video) – Real Python
Be it an integer or whatever, anything that we create in Python is actually an object. 04:15 And then we talked about variable references. So, you can think of, if you do something like n = 300, think of it as you’re creating a name for a reference that points to a specific object.
Published: December 10, 2019
Find elsewhere
🌐
Python
docs.python.org › 2.0 › ref › objects.html
3.1 Objects, values and types
It is understood that these resources are freed when the object is garbage-collected, but since garbage collection is not guaranteed to happen, such objects also provide an explicit way to release the external resource, usually a close() method. Programs are strongly recommended to explicitly close such objects. The `try...finally' statement provides a convenient way to do this. Some objects contain references to other objects; these are called containers.
🌐
Medium
medium.com › @matilitheory › how-python-handles-references-and-mutable-objects-315a6f344b31
How Python Handles References and Mutable Objects | by Matilitheory | Medium
October 12, 2025 - Variables don’t hold data they hold references. Mutable objects can be modified through any reference, while immutable ones result in new objects upon change. Understanding this principle prevents confusion, improves debugging, and deepens your comprehension of Python’s core memory semantics.
🌐
Medium
medium.com › geekculture › python-reference-e6458a9a0582
Python — Reference
August 9, 2022 - Variables in Python have a special attribute: identity, that is, “identity identification”. This special property is also called “reference” in many places. Let’s first take a look at one example: in languages ​​such as C++, variable declaration and assignment can be separated: ... If you directly use a variable that does not exist, an error will occur, NameError: name ‘a’ is not defined · In Python, when a = 343 is executed, it first creates the object 343 in memory, and then let a point to it, which is the reference.
🌐
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.
🌐
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
If there are no external references to the objects involved in a circular reference, their reference counts will not drop to zero, preventing garbage collection. To mitigate this, Python uses a cyclic garbage collector that can detect and collect circular references.
🌐
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 › @mklstudio80 › how-does-python-manage-references-to-objects-python-interview-2b4c5cf55247
How does Python manage references to objects? | Python Interview | by Mklstudio | Medium
June 6, 2025 - Python uses reference counting for real-time memory management. Garbage collector handles objects with circular references.
🌐
Tudelft
oit.tudelft.nl › learn-python › 2025 › objects › nutshell › object.html
4.1. Objects and References — Python for Civil Engineers
The following example illustrates the concept of object referencing in Python. By assigning one object to another, changes made to one object affect the other since they both point to the same object in memory.
🌐
CodeRivers
coderivers.org › blog › python-reference
Python References: Understanding, Using, and Best Practices - CodeRivers
February 22, 2026 - Python provides different ways to copy objects, such as shallow copies and deep copies. Shallow copies create a new object but the nested objects inside it are still referenced. Deep copies create completely independent objects with all nested objects copied as well.
🌐
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 - Python does not have a variable type declaration; the same variable can be reassigned to objects of different types without having to modify the variable’s space in memory. Similar to pointers in C, variables in Python do not store values directly; they work with references pointing to objects in memory.