Arguments are passed by assignment. The rationale behind this is twofold:

  1. the parameter passed in is actually a reference to an object (but the reference is passed by value)
  2. some data types are mutable, but others aren't

So:

  • If you pass a mutable object into a method, the method gets a reference to that same object and you can mutate it to your heart's delight, but if you rebind the reference in the method, the outer scope will know nothing about it, and after you're done, the outer reference will still point at the original object.

  • If you pass an immutable object to a method, you still can't rebind the outer reference, and you can't even mutate the object.

To make it even more clear, let's have some examples.

List - a mutable type

Let's try to modify the list that was passed to a method:

def try_to_change_list_contents(the_list):
    print('got', the_list)
    the_list.append('four')
    print('changed to', the_list)

outer_list = ['one', 'two', 'three']

print('before, outer_list =', outer_list)
try_to_change_list_contents(outer_list)
print('after, outer_list =', outer_list)

Output:

before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']

Since the parameter passed in is a reference to outer_list, not a copy of it, we can use the mutating list methods to change it and have the changes reflected in the outer scope.

Now let's see what happens when we try to change the reference that was passed in as a parameter:

def try_to_change_list_reference(the_list):
    print('got', the_list)
    the_list = ['and', 'we', 'can', 'not', 'lie']
    print('set to', the_list)

outer_list = ['we', 'like', 'proper', 'English']

print('before, outer_list =', outer_list)
try_to_change_list_reference(outer_list)
print('after, outer_list =', outer_list)

Output:

before, outer_list = ['we', 'like', 'proper', 'English']
got ['we', 'like', 'proper', 'English']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list = ['we', 'like', 'proper', 'English']

Since the the_list parameter was passed by value, assigning a new list to it had no effect that the code outside the method could see. The the_list was a copy of the outer_list reference, and we had the_list point to a new list, but there was no way to change where outer_list pointed.

String - an immutable type

It's immutable, so there's nothing we can do to change the contents of the string

Now, let's try to change the reference

def try_to_change_string_reference(the_string):
    print('got', the_string)
    the_string = 'In a kingdom by the sea'
    print('set to', the_string)

outer_string = 'It was many and many a year ago'

print('before, outer_string =', outer_string)
try_to_change_string_reference(outer_string)
print('after, outer_string =', outer_string)

Output:

before, outer_string = It was many and many a year ago
got It was many and many a year ago
set to In a kingdom by the sea
after, outer_string = It was many and many a year ago

Again, since the the_string parameter was passed by value, assigning a new string to it had no effect that the code outside the method could see. The the_string was a copy of the outer_string reference, and we had the_string point to a new string, but there was no way to change where outer_string pointed.

I hope this clears things up a little.

EDIT: It's been noted that this doesn't answer the question that @David originally asked, "Is there something I can do to pass the variable by actual reference?". Let's work on that.

How do we get around this?

As @Andrea's answer shows, you could return the new value. This doesn't change the way things are passed in, but does let you get the information you want back out:

def return_a_whole_new_string(the_string):
    new_string = something_to_do_with_the_old_string(the_string)
    return new_string

# then you could call it like
my_string = return_a_whole_new_string(my_string)

If you really wanted to avoid using a return value, you could create a class to hold your value and pass it into the function or use an existing class, like a list:

def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change):
    new_string = something_to_do_with_the_old_string(stuff_to_change[0])
    stuff_to_change[0] = new_string

# then you could call it like
wrapper = [my_string]
use_a_wrapper_to_simulate_pass_by_reference(wrapper)

do_something_with(wrapper[0])

Although this seems a little cumbersome.

Answer from Blair Conrad on Stack Overflow
🌐
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: >>> name = "Daenerys Targaryen" >>> title = name >>> id(title) 140606631565472 >>> id(name) 140606631565472 · The number is the same because the two variables are really references to the same object under the hood.
Top answer
1 of 16
3595

Arguments are passed by assignment. The rationale behind this is twofold:

  1. the parameter passed in is actually a reference to an object (but the reference is passed by value)
  2. some data types are mutable, but others aren't

So:

  • If you pass a mutable object into a method, the method gets a reference to that same object and you can mutate it to your heart's delight, but if you rebind the reference in the method, the outer scope will know nothing about it, and after you're done, the outer reference will still point at the original object.

  • If you pass an immutable object to a method, you still can't rebind the outer reference, and you can't even mutate the object.

To make it even more clear, let's have some examples.

List - a mutable type

Let's try to modify the list that was passed to a method:

def try_to_change_list_contents(the_list):
    print('got', the_list)
    the_list.append('four')
    print('changed to', the_list)

outer_list = ['one', 'two', 'three']

print('before, outer_list =', outer_list)
try_to_change_list_contents(outer_list)
print('after, outer_list =', outer_list)

Output:

before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']

Since the parameter passed in is a reference to outer_list, not a copy of it, we can use the mutating list methods to change it and have the changes reflected in the outer scope.

Now let's see what happens when we try to change the reference that was passed in as a parameter:

def try_to_change_list_reference(the_list):
    print('got', the_list)
    the_list = ['and', 'we', 'can', 'not', 'lie']
    print('set to', the_list)

outer_list = ['we', 'like', 'proper', 'English']

print('before, outer_list =', outer_list)
try_to_change_list_reference(outer_list)
print('after, outer_list =', outer_list)

Output:

before, outer_list = ['we', 'like', 'proper', 'English']
got ['we', 'like', 'proper', 'English']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list = ['we', 'like', 'proper', 'English']

Since the the_list parameter was passed by value, assigning a new list to it had no effect that the code outside the method could see. The the_list was a copy of the outer_list reference, and we had the_list point to a new list, but there was no way to change where outer_list pointed.

String - an immutable type

It's immutable, so there's nothing we can do to change the contents of the string

Now, let's try to change the reference

def try_to_change_string_reference(the_string):
    print('got', the_string)
    the_string = 'In a kingdom by the sea'
    print('set to', the_string)

outer_string = 'It was many and many a year ago'

print('before, outer_string =', outer_string)
try_to_change_string_reference(outer_string)
print('after, outer_string =', outer_string)

Output:

before, outer_string = It was many and many a year ago
got It was many and many a year ago
set to In a kingdom by the sea
after, outer_string = It was many and many a year ago

Again, since the the_string parameter was passed by value, assigning a new string to it had no effect that the code outside the method could see. The the_string was a copy of the outer_string reference, and we had the_string point to a new string, but there was no way to change where outer_string pointed.

I hope this clears things up a little.

EDIT: It's been noted that this doesn't answer the question that @David originally asked, "Is there something I can do to pass the variable by actual reference?". Let's work on that.

How do we get around this?

As @Andrea's answer shows, you could return the new value. This doesn't change the way things are passed in, but does let you get the information you want back out:

def return_a_whole_new_string(the_string):
    new_string = something_to_do_with_the_old_string(the_string)
    return new_string

# then you could call it like
my_string = return_a_whole_new_string(my_string)

If you really wanted to avoid using a return value, you could create a class to hold your value and pass it into the function or use an existing class, like a list:

def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change):
    new_string = something_to_do_with_the_old_string(stuff_to_change[0])
    stuff_to_change[0] = new_string

# then you could call it like
wrapper = [my_string]
use_a_wrapper_to_simulate_pass_by_reference(wrapper)

do_something_with(wrapper[0])

Although this seems a little cumbersome.

2 of 16
909

The problem comes from a misunderstanding of what variables are in Python. If you're used to most traditional languages, you have a mental model of what happens in the following sequence:

a = 1
a = 2

You believe that a is a memory location that stores the value 1, then is updated to store the value 2. That's not how things work in Python. Rather, a starts as a reference to an object with the value 1, then gets reassigned as a reference to an object with the value 2. Those two objects may continue to coexist even though a doesn't refer to the first one anymore; in fact they may be shared by any number of other references within the program.

When you call a function with a parameter, a new reference is created that refers to the object passed in. This is separate from the reference that was used in the function call, so there's no way to update that reference and make it refer to a new object. In your example:

def __init__(self):
    self.variable = 'Original'
    self.Change(self.variable)

def Change(self, var):
    var = 'Changed'

self.variable is a reference to the string object 'Original'. When you call Change you create a second reference var to the object. Inside the function you reassign the reference var to a different string object 'Changed', but the reference self.variable is separate and does not change.

The only way around this is to pass a mutable object. Because both references refer to the same object, any changes to the object are reflected in both places.

def __init__(self):         
    self.variable = ['Original']
    self.Change(self.variable)

def Change(self, var):
    var[0] = 'Changed'
Discussions

Storing references in variables
Hi, I am reading the book automate the boring stuff, 2nd edition and I came across the following example which describes how values and references work in python: >>> spam = 42 >>> cheese = spam >>> spam = 100 >>> spam 100 >>> cheese 42 " When you assign 42 to the spam variable, you are actually ... More on discuss.python.org
🌐 discuss.python.org
11
0
December 26, 2020
How is python pass by reference different from the original "pass by reference" concapt?
This is asked very frequently. The best explanation is here: https://nedbatchelder.com/text/names.html Note that this behaviour is not specific to Python: many modern languages, such as Java, JS, Ruby, and probably more, work the same way. More on reddit.com
🌐 r/learnpython
36
20
February 27, 2022
🌐
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.
🌐
Launch School
launchschool.com › books › python › read › variables_pointers
How Python objects and variables really work
The behaviors described in this ... objects. In Python, all variables are pointers to objects. If you assign the same object to multiple variables, every one of those variables references (points to) the same object....
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-variables
Python Variables - GeeksforGeeks
The variable y remains unchanged, still referencing the original object 5. Now, If we assign a new value to y: ... Python variables store references to objects, not the actual values themselves.
Published: 1 week ago
🌐
Python Tutorial
pythontutorial.net › home › advanced python › python references
Python References
March 27, 2025 - Summary: in this tutorial, you’ll have a good understanding of Python references and referencing counting. 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.
🌐
Medium
medium.com › @dreamferus › you-need-to-understand-variables-and-references-in-python-a-guide-51f0d480c083
You need to understand variables and references in Python — A guide
October 17, 2022 - A reference can be seen as the connection between a variable/name and a value, it contains the memory address where the value is held.
Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › python › pass-by-reference-vs-value-in-python
Pass by reference vs value in Python - GeeksforGeeks
June 3, 2026 - Explanation: List is mutated inside the function and the changes persist outside because both lst and a refer to the same object. In pass-by-value, a copy of the variable is passed, so changes inside the function don't affect the original. While Python doesn't strictly follow this model, immutable objects like int, str, and tuple behave similarly, as changes create new objects rather than modifying the original.
🌐
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.
Top answer
1 of 6
84

No, you cannot. As other answer point out, you can (ab?)use aliasing of mutable objects to achieve a similar effect. However, that's not the same thing as C++ references, and I want to explain what actually happens to avoid any misconceptions.

You see, in C++ (and other languages), a variable (and object fields, and entries in collections, etc.) is a storage location and you write a value (for instance, an integer, an object, or a pointer) to that location. In this model, references are an alias for a storage location (of any kind) - when you assign to a non-reference variable, you copy a value (even if it's just a pointer, it's still a value) to the storage location; when you assign to a reference, you copy to a storage location somewhere else. Note that you cannot change a reference itself - once it is bound (and it has to as soon as you create one) all assignments to it alter not the reference but whatever is referred to.

In Python (and other languages), a variable (and object fields, and entries in collections, etc.) is a just a name. Values are somewhere else (e.g. sprinkled all over the heap), and a variable refers (not in the sense of C++ references, more like a pointer minus the pointer arithmetic) to a value. Multiple names can refer to the same value (which is generally a good thing). Python (and other languages) calls whatever is needed to refer to a value a reference, despite being pretty unrelated to things like C++ references and pass-by-reference. Assigning to a variable (or object field, or ...) simply makes it refer to another value. The whole model of storage locations does not apply to Python, the programmer never handles storage locations for values. All he stores and shuffles around are Python references, and those are not values in Python, so they cannot be target of other Python references.

All of this is independent of mutability of the value - it's the same for ints and lists, for instance. You cannot take a variable that refers to either, and overwrite the object it points to. You can only tell the object to modify parts of itself - say, change some reference it contains.

Is this a more restrictive model? Perhaps, but it's powerful enough most of the time. And when it isn't you can work around it, either with a custom class like the one given below, or (equivalent, but less obvious) a single-element collection.

class Reference:
    def __init__(self, val):
        self._value = val # just refers to val, no copy

    def get(self):
        return self._value

    def set(self, val):
        self._value = val

That still won't allow you to alias a "regular" variable or object field, but you can have multiple variables referring to the same Reference object (ditto for the mutable-singleton-collection alternative). You just have to be careful to always use .get()/.set() (or [0]).

2 of 6
22

No, Python doesn't have this feature.

If you had a list (or any other mutable object) you could do what you want by mutating the object that both x and y are bound to:

>>> x = [7]
>>> y = x
>>> y[0] = 8
>>> print x
[8]

See it working online: ideone

🌐
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.
🌐
Python.org
discuss.python.org › python help
Storing references in variables - Python Help - Discussions on Python.org
December 26, 2020 - Hi, I am reading the book automate the boring stuff, 2nd edition and I came across the following example which describes how values and references work in python: >>> spam = 42 >>> cheese = spam >>> spam = 100 >>> spam 100 >>> cheese 42 " When you assign 42 to the spam variable, you are actually creating the 42 value in the computer’s memory and storing a reference to it in the spam variable.
🌐
The Python Coding Stack
thepythoncodingstack.com › the python coding stack › if you haven't got a clue what "pass by value" or "pass by reference" mean, read on…
If You Haven't Got A Clue What "Pass By Value" or "Pass By Reference" mean, read on…
August 20, 2024 - In the program above, you create ... identity. You also assign it to the variable name original_recipe. A variable name in Python is a reference to an object....
🌐
Reddit
reddit.com › r/learnpython › how is python pass by reference different from the original "pass by reference" concapt?
r/learnpython on Reddit: How is python pass by reference different from the original "pass by reference" concapt?
February 27, 2022 -

Trying to understand how Python works passing arguments in functions. I've heard that Python's approach is referred to as "pass by assignment" or "pass by object reference".

How does this differ from the more traditional "pass by reference" approach? Hopefully someone can explain it in a way that's easy to understand.

🌐
Real Python
realpython.com › python-variables
Variables in Python: Usage and Best Practices – Real Python
April 15, 2026 - In Python, variables are names associated with concrete objects or values stored in your computer’s memory. By associating a variable with a value, you can refer to the value using a descriptive name and reuse it as many times as needed in your code.
🌐
Tutorial Teacher
tutorialsteacher.com › articles › how-to-pass-value-by-reference-in-python
How to pass value by reference in Python?
Hence, it can be inferred that in Python, a function is always called by passing a variable by reference. It means, if a function modifies data received from the calling environment, the modification should reflect in the original data.
🌐
Medium
medium.com › the-system-builder-journal › variable-and-memory-references-in-python-29f976772ad3
Variable and memory references in Python | by Rohit Patil
February 5, 2026 - Welcome to the first article in my new series, where I’ll explain some important ideas about Python that many beginners often miss. At first glance, it might appear that defining a variable is a straightforward process — you assign a value, and it’s ready for use. However, beneath this apparent simplicity lies a deeper mechanism. When we declare a variable, it’s not merely a container for data; it’s a reference to a specific location in the computer’s memory where the actual data resides.
🌐
Real Python
realpython.com › python-pass-by-reference
Pass by Reference in Python: Background and Best Practices – Real Python
March 18, 2026 - Free Bonus: 5 Thoughts On Python Mastery, a free course for Python developers that shows you the roadmap and the mindset you’ll need to take your Python skills to the next level. Before you dive into the technical details of passing by reference, it’s helpful to take a closer look at the term itself by breaking it down into components: Pass means to provide an argument to a function. By reference means that the argument you’re passing to the function is a reference to a variable that already exists in memory rather than an independent copy of that variable.
🌐
Web Reference
webreference.com › python › basics › variables
Understanding the basics of variables in Python
In Python, variables do not store values directly. Instead, they store references to objects that contain the values.