If pfunc is an arbitrary Python function (with EventArgs as arguments), then I think you need a bridge between that Python object (pfunc) and the EventHandler type. One way might be to add a C-level wrapper function (with EventHandler signature) that when called executes the python level function us… Answer from hansgeunsmeyer on discuss.python.org
🌐
Reddit
reddit.com › r/learnpython › why is there no concept of a pointer or pass-by reference in python? is there something i can use
r/learnpython on Reddit: Why is there no concept of a pointer or pass-by reference in python? Is there something I can use
August 10, 2022 -

I am a C++ and assembly developer mainly, but as someone entering the job market that just doesn't cut it. I have a job I got hired for where I'm taking 4+ years of a python codebase that no one has documented and is spaghetti and updating it, and was supposed to be adding multithreading (EXCEPT THERE IS NO TRUE MULTITHREADING SO I HAVE TO DO MULTIPROCESSING WHICH IS A CLUSTER-F***). So that blows.

BUT

why is there no pointers!? or way to go references? I need to store data in an object that gets passed into some libraries, and then the library runs callbacks where I analyze the crap. From there I need to set the values so in other callbacks I can work with the values. It's a dictionary so I can add some new keys to store the data... except I can't because it's like pass by value so the data instantly gets deleted once it returns from the callback. If I passed in a pointer I'd be set, except that's not possible...

That's just one issue in a mirad of issues I'm facing with this junk language. Not to even mention the horribleness of everything using like 2gb of memory because each process copies the entire memory space of the head process....

Please tell me there's some kinda object or pointer thing I can use.

EDIT : I got the help I needed here, thanks everyone! sorry to trash the language a bit above I was just frustrated lol

Top answer
1 of 4
13
Holy cow calm down. EXCEPT THERE IS NO TRUE MULTITHREADING Lol yes there is. The threading module makes real threads. If you are upset about the GIL you just need to learn how to use it. why is there no pointers!? All python names are pointers. It's incredibly hard not to use a pointer. No idea what you are doing but if you mutate a dictionary in a function you will see it in the calling scope. >>> def add_data(d): ... d['Fuck-Me-With-RAM'] = 'pure zen' ... >>> data = {} >>> add_data(data) >>> data {'Fuck-Me-With-RAM': 'pure zen'} Read this: https://nedbatchelder.com/text/names.html this junk language Cheers, don't let the door hit ya
2 of 4
4
EXCEPT THERE IS NO TRUE MULTITHREADING SO I HAVE TO DO MULTIPROCESSING WHICH IS A CLUSTER-F*** If that's an issue for you then someone used the wrong tool for the wrong job. That said: most of the time asyncio's single-threaded event loop will do just fine. why is there no pointers!? Why should there be? It's a high-level language with a garbage collector. or way to go references? For any collection type or class you're already getting effectively pass-by-reference, but if you mean why won't def foo(x): x = 2 x = 1 foo(x) # x is still 1 here change x to 2: because in python there's no reason it should. Spooky action at a distance is generally discouraged and, just like in C/C++ you should avoid when you reasonably can. It's a dictionary so I can add some new keys to store the data... except I can't because it's like pass by value so the data instantly gets deleted once it returns from the callback. Dictionaries are not passed by value. def foo(x): x["new_key"] = "it's here" y = {} foo(y) print(y) A bit more technically: everything is effectively passed by reference, the language simply (deliberately) has immutable values for integers, floats, strings, and most 'primitive' types like that so there exists no way to express the concept of "edit the value of the python object this variable currently points at" for those primitives. The concept absolutely does exist for objects in general - anything done via the name (as opposed to reassigning the name) acts on the underlying python object. That's why the dictionary key is persisted in y outside the function in my example.
🌐
Real Python
realpython.com › pointers-in-python
Pointers in Python: What's the Point? – Real Python
March 18, 2026 - Python throws an error, explaining that add_one() wants a pointer instead of just an integer. Luckily, ctypes has a way to pass pointers to these functions.
Discussions

function - Without pointers, can I pass references as arguments in Python? - Stack Overflow
Since Python doesn't have pointers, I am wondering how I can pass a reference to an object through to a function instead of copying the entire object. This is a very contrived example, but say I am More on stackoverflow.com
🌐 stackoverflow.com
python - How do I pass a variable by reference? - Stack Overflow
Mutable arguments are effectively ... way C passes arrays as pointers—mutable objects can be changed in place in the function, much like C arrays. ... Save this answer. ... Show activity on this post. There are a lot of insights in answers here, but I think an additional point is not clearly mentioned here explicitly. Quoting from Python documentation ... More on stackoverflow.com
🌐 stackoverflow.com
variables - Please explain Python's "pass-by-pointer" approach - Stack Overflow
a = 5 a is not holding the value 5 itself but only an address to the object 5, correct? So it is a reference variable. b = a Now it seems to me that b, instead of again holding the address of a, is More on stackoverflow.com
🌐 stackoverflow.com
March 17, 2018
Passing pointer from c++ to python - Numba - Numba Discussion
Hi To pass CPU pointer from c++ to python numpy I am using this code np_arg = reinterpret_cast (PyArray_SimpleNewFromData(ND, dims, NPY_LONGDOUBLE, reinterpret_cast (c_arr))); My question is how to pass c++ GPU pointer to python numba ? Thanks More on numba.discourse.group
🌐 numba.discourse.group
0
August 21, 2022
🌐
Python.org
discuss.python.org › python help
How to pass a python function to a C function as a function pointer in Cython - Python Help - Discussions on Python.org
February 7, 2024 - Hi all, I am writing a cython class like this. cdef class Button: cdef CButton* ptr cdef object _onClick def __cinit__(self, ...): self.ptr = make_btn_ptr_in_C() @onClick.setter def onClick(self, pfunc): self._onClick = pfunc setClickHandler(self.ptr, self._onClick) This setClickHandler ...
Top answer
1 of 2
19

Your understanding is, unfortunately, completely wrong. Python does not copy the value, nor does it allocate space for a new one. It passes a value which is itself a reference to the object. If you modify that object (rather than rebinding its name), then the original will be modified.

Edit

I wish you would stop worrying about memory allocation: Python is not C++, almost all of the time you don't need to think about memory.

It's easier to demonstrate rebinding via the use of something like a list:

def my_func(foo):
    foo.append(3)  # now the source list also has the number 3
    foo = [3]      # we've re-bound 'foo' to something else, severing the relationship
    foo.append(4)  # the source list is unaffected
    return foo


original = [1, 2]
new = my_func(original)

print original     # [1, 2, 3]
print new          # [3, 4]

It might help if you think in terms of names rather than variables: inside the function, the name "foo" starts off being a reference to the original list, but then we change that name to point to a new, different list.

2 of 2
3

Python parameters are always "references".

The way parameters in Python works and the way they are explained on the docs can be confusing and misleading to newcomers to the languages, specially if you have a background on other languages which allows you to choose between "pass by value" and "pass by reference".

In Python terms, a "reference" is just a pointer with some more metadata to help the garbage collector do its job. And every variable and every parameter are always "references".

So, internally, Python pass a "pointer" to each parameter. You can easily see this in this example:

>>> def f(L):
...     L.append(3)
... 
>>> X = []
>>> f(X)
>>> X
[3]

The variable X points to a list, and the parameter L is a copy of the "pointer" of the list, and not a copy of the list itself.

Take care to note that this is not the same as "pass-by-reference" as C++ with the & qualifier, or pascal with the var qualifier.

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'
🌐
Python
docs.python.org › 2.5 › lib › ctypes-passing-pointers.html
14.14.1.9 Passing pointers (or: passing parameters by reference)
December 23, 2008 - ctypes exports the byref function which is used to pass parameters by reference. The same effect can be achieved with the pointer function, although pointer does a lot more work since it constructs a real pointer object, so it is faster to use byref if you don't need the pointer object in Python itself:
🌐
Sololearn
sololearn.com › en › Discuss › 2681911 › python-pass-by-value-and-pass-by-pointerchange-value-of-variable-when-calling-function
python pass by value and pass by pointer;change value of variable when calling function; | Sololearn: Learn to code for FREE!
void fun(int *anyint) { *anyint = 200; } int main(){ int var=100; cout<<"var before fun call "<<var<<endl; //o/p=>var=100 fun(&var); cout<<"var after fun call "<<var<<endl; //o/p=>var=200 } ----------------------------------- in python i didnt find any way to perform like above c++ code var = 100 def fun(anyvar): anyvar = 200 print("anyvar value inside fun ",anyvar) print("var value before fun call ",var) fun(var) print("var value after fun call ",var) i want to change the value of variable 'var' when calling the function 'fun()'; variable name 'var' is not fixed it may vary .is it any way?
Find elsewhere
🌐
freeCodeCamp
freecodecamp.org › news › how-passing-by-object-reference-works-in-python
How Passing by Object Reference Works in Python
March 26, 2026 - Python doesn't use call by value or call by reference. It passes by object reference, where the function receives a reference to the object, and whether that object can be modified in place determines what happens next.
🌐
Google Groups
groups.google.com › g › cython-users › c › 0ouYUUa60R4
passing a pointer function to another function which can be called in python
September 24, 2017 - Yes, list_apply calls the function contained in the wrapper directly, without python function call overhead, but before doing that if goes through the process of converting the argument (given as a python object) to a C_double, and it does the same in reverse for the result. But once you've mastered the mechanics of passing around function pointers in wrappers, you can figure out how to get performance benefit from it.
🌐
Quora
quora.com › How-do-I-pass-a-variable-by-reference-in-Python
How to pass a variable by reference in Python - Quora
Answer (1 of 4): Strictly speaking the only thing passed to a function are references - you can check this using the id function (id returns the unique id of the object, so if two ids are the same it is because they are the same object). [code]def my_func(x): return id(x) a = 17 id(a) == my_fu...
🌐
GeeksforGeeks
geeksforgeeks.org › python › using-pointers-in-python-using-ctypes
Using Pointers in Python using ctypes - GeeksforGeeks
July 23, 2025 - In contrast, POINTER() is a factory function that creates and returns a new ctypes pointer type. Pointer types are cached and reused internally, the parameter which we will pass in POINTER() must be of ctypes.
🌐
Medium
medium.com › @devyjoneslocker › understanding-pythons-pass-by-assignment-in-the-backdrop-of-pass-by-value-vs-9f5cc602f943
Python : What is it? Pass by Value or Pass by Reference? It is Pass by Assignment | Medium
June 10, 2023 - Modifying the copy within the function does not affect the original value. ... On the other hand, in languages that adhere to the “pass by reference” concept, a reference or pointer to the original object is passed to the function.
🌐
Numba Discussion
numba.discourse.group › t › passing-pointer-from-c-to-python › 1523
Passing pointer from c++ to python - Numba - Numba Discussion
August 21, 2022 - Hi To pass CPU pointer from c++ to python numpy I am using this code np_arg = reinterpret_cast<PyArrayObject*>(PyArray_SimpleNewFromData(ND, dims, NPY_LONGDOUBLE, reinterpret_cast<void*>(c_arr))); My question is how t…
🌐
Real Python
realpython.com › python-pass-by-reference
Pass by Reference in Python: Background and Best Practices – Real Python
March 18, 2026 - After gaining some familiarity with Python, you may notice cases in which your functions don’t modify arguments in place as you might expect, especially if you’re familiar with other programming languages. Some languages handle function arguments as references to existing variables, which is known as pass by reference.
🌐
FavTutor
favtutor.com › blogs › pass-by-reference-in-python
Pass by Reference in Python | With Examples
October 7, 2023 - Pass by Reference: In contrast, pass by reference involves passing a reference to the original data or object rather than a copy. Any changes made to the referenced object inside a function or operation are reflected in the original object. Let's now look at how Python handles this.
🌐
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.

🌐
Tutorial Teacher
tutorialsteacher.com › articles › how-to-pass-value-by-reference-in-python
How to pass value by reference in Python?
Python's built-in id() function returns this id, which is roughly equivalent to a memory address.
🌐
Launch School
launchschool.com › books › python › read › variables_pointers
How Python objects and variables really work
This chapter examines the concepts behind variables and pointers. Specifically, we'll see how Python variables are pointers to a location in memory (an address space) that contains the object assigned to the variable. New programmers often struggle to master this concept, but the material is crucial.
🌐
McNeel Forum
discourse.mcneel.com › rhino developer
Basic Python - Are values passed by reference or not? - Rhino Developer - McNeel Forum
April 18, 2022 - Hi, I have a basic python question: does python functions passes values by reference or not? The reason to ask is below. The function below cannot modify point and thus the output is the same point3d(0,0,0) #RhinoCommon library import Rhino.Geometry as r def change_point(pt): pt = r.Point3d(100,0,0) #create point and run change_point method pt = r.Point3d(0,0,0) change_point(pt) #output a = pt And this one modify the value and returns point3d(100,0,0) #RhinoCommon library impo...