Here's a utility function based on a (now-deleted) comment made by "Tiran" in a weblog discussion @Hophat Abc references in his own answer that will work in both Python 2 and 3.

Disclaimer: If you read the the linked discussion, you'll find that some folks think this is so unsafe that it should never be used (as likewise mentioned in some of the comments below). I don't agree with that assessment but feel I should at least mention that there's some debate about using it.

import _ctypes

def di(obj_id):
    """ Inverse of id() function. """
    return _ctypes.PyObj_FromPtr(obj_id)

if __name__ == '__main__':
    a = 42
    b = 'answer'
    print(di(id(a)))  # -> 42
    print(di(id(b)))  # -> answer
Answer from martineau on Stack Overflow
🌐
Sololearn
sololearn.com › en › Discuss › 1269415 › how-to-dereference-object
How to Dereference object? | Sololearn: Learn to code for FREE!
This may be because the member access operator is evaluated before the dereference operator. Try (*p).func() 10th May 2018, 11:17 AM · Vlad Serbu · + 1 · Thanks! It worked. 10th May 2018, 11:19 AM · Munna Aziz Rahaman · Answer · Learn more efficiently, for free: Introduction to Python ·
Discussions

python - Is it possible to dereference variable id's? - Stack Overflow
Can you dereference a variable id retrieved from the id function in Python? For example: dereference(id(a)) == a I want to know from an academic standpoint; I understand that there are more practi... More on stackoverflow.com
🌐 stackoverflow.com
python - How to "dereference" a dictionary? - Stack Overflow
you have to create deep copies of all your objects when passing them anywhere during creation - docs.python.org/3/library/copy.html More on stackoverflow.com
🌐 stackoverflow.com
python - Dereference variables at class initialization - Stack Overflow
Communities for your favorite technologies. Explore all Collectives · Ask questions, find answers and collaborate at work with Stack Overflow for Teams More on stackoverflow.com
🌐 stackoverflow.com
In Python, what's the difference between a variable, an object, a reference, and a value?
What is a variable? A variable is a name that is bound to a non-null pointer to an object (a PyObject*, in CPython). Critically, None is also a non-null PyObject*. What is an object? An object is a PyObject whose data has been allocated on the heap. Crucially, a PyObject might exist for some time after nothing is pointing to it; it takes time for the garbage collector to step in and free the memory. What is a value? A value is the collective state of an object's members. In other words, in C, a PyObject is a struct, and the value of the object is the data inside all of the various members that it could contain. Now, let's look at your example. You are allocating memory for a new PyLongObject on the heap, and x now points to that object. Calling id(x) returns the contents of that pointer (a location in memory). Next, you allocate a new integer PyLongObject on the heap, and x now points to that object. The old object no longer has any references pointing to it, and will just sit there orphaned until the garbage collector frees it. What's the value? The value is the collective state of the members of that PyLongObject, whatever the implementation actually to define the data inside the object. In CPython, it's an array of uint32_ts. More on reddit.com
🌐 r/learnprogramming
7
1
November 17, 2022
🌐
Real Python
realpython.com › pointers-in-python
Pointers in Python: What's the Point? – Real Python
March 18, 2026 - As above, x and y are both names that point to the same Python object. But the Python object that holds the value 1000 is not always guaranteed to have the same memory address. For example, if you were to assign a literal 1000 to y as well, you would end up with a different memory address:
🌐
Python
docs.python.org › 3 › library › weakref.html
weakref — Weak references
The WeakKeyDictionary and WeakValueDictionary classes supplied by the weakref module are an alternative, using weak references to construct mappings that don’t keep objects alive solely because they appear in the mapping objects. If, for example, an image object is a value in a WeakValueDictionary, then when the last remaining references to that image object are the weak references held by weak mappings, garbage collection can reclaim the object, and its corresponding entries in weak mappings are simply deleted.
🌐
PyPI
pypi.org › project › jsonref
jsonref · PyPI
jsonref is a library for automatic dereferencing of JSON Reference objects for Python (supporting Python 3.7+). This library lets you use a data structure with JSON reference objects, as if the references had been replaced with the referent data. >>> from pprint import pprint >>> import jsonref >>> # An example json document >>> json_str = """{"real": [1, 2, 3, 4], "ref": {"$ref": "#/real"}}""" >>> data = jsonref.loads(json_str) >>> pprint(data) # Reference is not evaluated until here {'real': [1, 2, 3, 4], 'ref': [1, 2, 3, 4]}
🌐
Llllllllll
llllllllll.github.io › principles-of-performance › python-overview.html
Python Overview — principles-of-performance documentation
Because the size of each value differs depending on the type, which cannot be known ahead of time because Python is dynamically typed, Python just refers to all objects through a pointer to the value struct. All we know is that the first member of the value struct will be a pointer to some collection of functions which will be designed to know the true size of the object and how to interpret the data. This means that at minimum we must do one memory dereference to perform any operation on a Python object.
🌐
Python Morsels
pythonmorsels.com › pointers
Variables and objects in Python - Python Morsels
February 28, 2022 - The above example was borrowed from Django. Don't mutate the objects passed-in to your function unless the function caller expects you to. ... Both of these techniques make a new list which points to the same objects as the original list. The two lists are distinct, but the objects within them are the same: >>> numbers is my_numbers False >>> numbers[0] is my_numbers[0] True · Since integers (and all numbers) are immutable in Python we don't really care that each list contains the same objects because we can't mutate those objects anyway.
Find elsewhere
🌐
Quora
quora.com › What-exactly-does-the-term-dereferencing-an-object-mean
What exactly does the term “dereferencing” an object mean? - Quora
Answer (1 of 4): In computer language design there three ways to pass a value to a function. They are referred to as “Call by Name”, “Call by Value”, and “Call by Reference”. Call by Name With a “Call by Name” language, the names used in the parameter list of the calling function ...
🌐
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 - When the count reaches zero, it indicates that no active references point to the object, making it eligible for garbage collection. This mechanism allows Python to automatically handle memory deallocation, optimize resources, and manage object lifecycles effectively.
🌐
Python
docs.python.org › 2.5 › lib › ctypes-pointers.html
14.14.1.14 Pointers
December 23, 2008 - TypeError: expected c_long instead of int >>> PI(c_int(42)) <ctypes.LP_c_long object at 0x...> >>> Calling the pointer type without an argument creates a NULL pointer. NULL pointers have a False boolean value: >>> null_ptr = POINTER(c_int)() >>> print bool(null_ptr) False >>> ctypes checks for NULL when dereferencing pointers (but dereferencing non-NULL pointers would crash Python):
🌐
GeeksforGeeks
geeksforgeeks.org › python › using-pointers-in-python-using-ctypes
Using Pointers in Python using ctypes - GeeksforGeeks
July 23, 2025 - As we can see that if we try to print this void pointer as it doesn't point to any value it just points to the type it can store i.e long (ctypes by default converts int to long). Notice one thing here we have used POINTER() instead of pointer that's because the pointer() function creates a new pointer instance, pointing to an object.
🌐
Reddit
reddit.com › r/learnprogramming › in python, what's the difference between a variable, an object, a reference, and a value?
r/learnprogramming on Reddit: In Python, what's the difference between a variable, an object, a reference, and a value?
November 17, 2022 -

I've been discussing Python semantics with a friend who's helped me a lot in the past with understanding programming concepts and he keeps saying that a Python variable is "a name bound to a reference" and "the object on the other side of the reference has a type and a value" while the variable itself doesn't. He's been trying to explain what he means, but I'm not just not fully understanding, so I'm hoping someone here can explain in a way that will make more sense to me.

I think part of why I'm struggling is that I'm very comfortable with the idea of variables and pointers in C because I first learned programming in C++ from a professor whose examples were very C-style, and because I completed an 8 month firmware internship which was primarily low-level c programming. So at this point, the idea of a variable as being fundamentally linked to a physical memory location is kind of stuck in my head. I tend to think of C variables as just labels for memory addresses and, in CPython at least, I know a Python variable's ID (obtained via the id function) IS just the memory address (that's what the CPython documentation says at least). But I also know that if I do something like,

x = 5
print(id(x))

x = 50
print(id(x))

it will print out two different values. My friend said that's because the id doesn't really belong to the variable itself, but to the object. So is the first ID number that would be printed by the above code then a reference to the ID of the object 5? But then, if 5 is an object, what's the value?

Top answer
1 of 3
4
What is a variable? A variable is a name that is bound to a non-null pointer to an object (a PyObject*, in CPython). Critically, None is also a non-null PyObject*. What is an object? An object is a PyObject whose data has been allocated on the heap. Crucially, a PyObject might exist for some time after nothing is pointing to it; it takes time for the garbage collector to step in and free the memory. What is a value? A value is the collective state of an object's members. In other words, in C, a PyObject is a struct, and the value of the object is the data inside all of the various members that it could contain. Now, let's look at your example. You are allocating memory for a new PyLongObject on the heap, and x now points to that object. Calling id(x) returns the contents of that pointer (a location in memory). Next, you allocate a new integer PyLongObject on the heap, and x now points to that object. The old object no longer has any references pointing to it, and will just sit there orphaned until the garbage collector frees it. What's the value? The value is the collective state of the members of that PyLongObject, whatever the implementation actually to define the data inside the object. In CPython, it's an array of uint32_ts.
2 of 3
3
So at this point, the idea of a variable as being fundamentally linked to a physical memory location is kind of stuck in my head. Yeah, I think you should unlink this idea. This is not a universally true statement, since different languages will have fundamentally different "concepts" or "models" of memory. This in turn means that the definition of a "variable" will change from language to language. I think this is easiest to explain by comparing and contrasting C with Python Lower-level languages like C fundamentally conceptualizes memory as a giant array of bytes split into two parts: the stack and the heap. Whenever you create a variable, you are reserving a small chunk of bytes on this "stack". You can store small quantities of data here -- things like ints, floats... If you want to store larger quantities of data, you typically do so on the heap. You ask your runtime (e.g. your operating system) permission to use a certain range of bytes (e.g. via malloc) and stick your data there. But in order to actually use this data, you now need to keep track of which specific index within this giant array your data starts at. We call these "memory addresses". And where can we store these indexes? Well, typically within one of your variables on the stack. So when we are doing a pointer dereference (e.g. *my_variable), what we are doing is: Looking at the specific chunk of bytes on the stack associated with my_variable. Reading the data located within those bytes Interpreting those bytes as an index within this giant bytes array. Grabbing the data starting at that index. Of course, everything I described above is a giant over-simplification and a lie. For example: Most modern-day operating systems don't literally represent memory as a giant array of bytes and instead split them up into discrete chunks called "pages". This enables them to do things like swap pages in and out of disk to allow programs to use more RAM then is physically present on the machine. This in turn means that the "memory address" is also a bit of an illusion. You are typically being given a "virtual memory address" which your operating system will under the hood map to a "physical memory address". This mapping will change as data is paged in and out, since where your data is literally stored on your physical RAM can change over time. Your variable does not necessarily need to correspond to something on the stack. Your compiler may opt to not bother storing any data there, and instead use your CPU's registers instead. This is done for efficiency purposes, since reading/writing to a register is faster then reading/writing to RAM. Most modern-day CPUs do a lot of clever caching whenever you read data from RAM. Instead of literally fetching data byte-for-byte from RAM, it pre-emptively fetches a whole bunch of bytes at once and stores it within a cache within your CPU. This helps speed up code that tries reading bytes in sequential order -- and can lead to unexpected slowness in code that doesn't. C's model by itself wouldn't give you any way of predicting this behavior. That said, you can mostly get away with ignoring all of the above implementation details. C's model and abstractions are consistent and self-contained and is sufficient for understanding how to write well-formed C programs. Higher-level programming languages like Python have a very different model. Python does still sort of have the concept of a stack and a heap, but that's about where the similarities with C end. In particular, unlike C Python does not have any concept of memory being a giant array nor any concept of memory having an address. Instead, it conceptualizes the stack as being literally the stack data structure (with push/pop operations), where each entry in the stack is a key-value map (e.g. a hashmap or dictionary). A variable is just a key within this dict. You can actually modify this stack frame dict directly. For example, try running the following from the Python IDE. >>> my_variable = 3 >>> stack_frame = locals() >>> stack_frame["my_variable"] = "surprise" >>> print(my_variable) surprise The locals() builtin function will return a reference to the current stack frame dict. We can then modify that dict directly to change out what our variable happens to be referring to. (Does this mean we can dynamically create new variables? Yes -- try doing stack_frame["brand_new_variable"] = 101; print(brand_new_variable)) Python's concept of a "heap" is even more abstract. In Python, the heap is just a space where objects can be stored. These objects are not stored at a particular memory address nor are in any particular order: the heap is basically one giant bag of stuff. These objects are given a unique integer id. You can imagine that's how the stack frame dict is keeping track of each object under the hood: a stack frame is a mapping of strings (variable names) to object ids, and the heap is a mapping of object ids to the underlying object. This is the mechanism by which a Python variable refers to an object. But I prefer to conceptualize this more visually. To me, a variable in Python is an arrow with a name that points to some object floating in the aether. Thinking about what's happening in terms of these "object ids" is honestly a bit too cumbersome to be useful in practice. And what exactly is an object? Well, either: A glorified wrapper around a dict, for user-defined classes Or special "primitive" object that the Python interpreter creates on your behalf Just like with C, this model is a gross oversimplification of what's actually happening under the hood. And like C, this model is internally consistent and self-contained, so you mostly don't need to worry about the implementation details. Granted, Python's model does break down a bit more frequently then C's does. For example, you do need to mentally consider how everything maps to the underlying physical memory if you care about performance. You also need to start caring about C's model if you want to write Python wrappers around C code. I know a Python variable's ID (obtained via the id function) IS just the memory address (that's what the CPython documentation says at least) This is just an implementation detail. It's true today, but CPython is under no obligation to continue using the memory address as the unique ID in the future. Similarly, other implementations of Python may choose to use something completely different. (That said, it's unlikely in practice that CPython will stop using the memory address as the unique id any time soon. Switching to something else would probably make it harder to implement the model we discussed above.) My friend said that's because the id doesn't really belong to the variable itself, but to the object. Yup, this is absolutely correct. So is the first ID number that would be printed by the above code by then a reference to the ID of the object 5? No: what's printed is literally the id of the object 5. If we want to be more precise, here's what's happening when we do print(id(x)): Python evaluates the expression x. To do this, it looks at the current stack frame dict, looks up the key "x", then grabs the object id -- a reference to an object representing the integer 5. Let's say for the sake of argument that this object id is 3017463234928. The x variable is evaluated to this object reference. The id(...) function accepts this object reference -- the 3017463234928 object id. It does some Magic™ and creates a new int object that represents the number 3017463234928. (Why does it bother creating an object? Well, because Python's model states that every value the user interacts with must be represented as an object). Anyways, the 3017463234928 int object is stored on the heap. Let's say this new int object has an id of 4999584263006. The id(x) expression evaluates to this object reference. The print(...) function accepts the 4999584263006 object id. It uses that to look up the underlying object, reads it, and prints out 3017463234928 to stdout. Visually, I guess this ends up looking sort of like this: +--------------------------+ | object id: 3017463234928 | x -------------> | type: int | | value: 5 | +--------------------------+ +--------------------------+ | object id: 4999584263006 | id(x) ---------> | type: int | | value: 3017463234928 | +--------------------------+ It's a bit weird to have id(x) point to something -- it's not a variable, after all. But hopefully you get the idea. But then, if 5 is an object, that what's the value? This is a bit easier to explain using custom objects instead of Python's builtin ones. Consider the following: >>> class Url: ... def __init__(self, domain, path): ... self.domain = domain ... self.path = path ... >>> >>> a = Url("reddit.com", "/r/learnprogramming") >>> b = Url("reddit.com", "/r/learnprogramming") >>> c = Url("reddit.com", "/r/aww") This is creating three separate Url objects: two representing reddit.com/r/learnprogramming and one representing reddit.com/r/aww. But how many distinct "entities" or "values" do we have? Arguably, just two. The a and b variables may be pointing to two distinct objects, but what they fundamentally represent is the same. So, we say those two objects have the same "value": the same high-level "meaning" or "data". But then, if 5 is an object, that what's the value? The "value" is the integer 5. Python will represent this integer using an int object.
🌐
Codementor
codementor.io › community › variable references in python
Variable references in Python | Codementor
April 22, 2019 - For example in a=1, an object with value '1' is created in memory and a reference 'a' now points to it. Because I switched to python after programming in C for a while, I used to think that if I ...
Top answer
1 of 3
21

You need to hold a reference to an object (i.e. assign it to a variable or store it in a list).

There is no language support for going from an object address directly to an object (i.e. pointer dereferencing).

2 of 3
16

You're almost certainly asking the wrong question, and Raymond Hettinger's answer is almost certainly what you really want.

Something like this might be useful trying to dig into the internals of the CPython interpreter for learning purposes or auditing it for security holes or something… But even then, you're probably better off embedding the Python interpreter into a program and writing functions that expose whatever you want into the Python interpreter, or at least writing a C extension module that lets you manipulate CPython objects.

But, on the off chance that you really do need to do this…

First, there is no reliable way to even get the address from the repr. Most objects with a useful eval-able representation will give you that instead. For example, the repr of ('1', 1) is "('1', 1)", not <tuple at 0x10ed51908>. Also, even for objects that have no useful representation, returning <TYPE at ADDR> is just an unstated convention that many types follow (and a default for user-defined classes), not something you can rely on.

However, since you presumably only care about CPython, you can rely on id:

CPython implementation detail: This is the address of the object in memory.

(Of course if you have the object to call id (or repr) on, you don't need to dereference it via pointer, and if you don't have the object, it's probably been garbage collected so there's nothing to dereference, but maybe you still have it and just can't remember where you put it…)

Next, what do you do with this address? Well, Python doesn't expose any functions to do the opposite of id. But the Python C API is well documented—and, if your Python is built around a shared library, that C API can be accessed via ctypes, just by loading it up. In fact, ctypes provides a special variable that automatically loads the right shared library to call the C API on, ctypes.pythonapi.

In very old versions of ctypes, you may have to find and load it explicitly, like pydll = ctypes.cdll.LoadLibrary('/usr/lib/libpython2.5.so') (This is for linux with Python 2.5 installed into /usr/lib; obviously if any of those details differ, the exact command line will differ.)

Of course it's much easier to crash the Python interpreter doing this than to do anything useful, but it's not impossible to do anything useful, and you may have fun experimenting with it.

🌐
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.
🌐
Python
mail.python.org › pipermail › edu-sig › 2008-May › 008547.html
[Edu-sig] How does Python do Pointers?
May 6, 2008 - No >matter what you do in the function, the actual parameter still contains >the same thing, a reference to the same object it was always pointing to >at the time of call. That's because the function operates on it own copy >of that reference, not the _actual_variable_ of the caller. > >Summary: Python's parameter passing is just call by value. But Python >variable values are always references and Python semantics dictates that >those values are dereferenced when variables are used in expressions.