People sometimes ask, “Does Python have pointers?” I hate to be the typical senior engineer, but this is one of those questions where the answer is, it depends what you mean by pointer.
The classic definition of a pointer is: a variable that holds the address of something else and that you can use to work with that something else. In very broad pseudo-code, it would be something like this:
myvar = SOMETHING;
mypointer = get_address_of(myvar);
print(get_value_via_pointer(mypointer));
## output is SOMETHING
This is useful because we can use a pointer to refer to data, setting the pointer in one part of the code with whatever logic we need to decide what data it should point to. Then elsewhere we can use the pointer without having to know what it’s referring to or how the decision was made. The pointer gives us an indirection that lets us separate concerns and write more modular code.
Many programming languages provide a pointer facility like this. For
example, in C, the get_address_of()
operation is ampersand, and the
get_value_via_pointer()
operation is star, and our code snippet would be:
int myvar = 17;
int *mypointer = &myvar;
print_int(*mypointer); // outputs 17
Other languages like C++, C#, Go, Rust, Pascal, and even Fortran have similar capabilities.
OK, so what about Python? In one sense, Python doesn’t have a pointer
concept like this. You could say that get_address_of()
is provided by Python’s
id()
function, since (in CPython at least) it returns the memory address of the
data:
myvar = 17
mypointer = id(myvar) # ** not useful
But Python has no inverse operation: there’s no get_value_via_pointer()
that can get you myvar
given mypointer
.
So Python doesn’t have the classic pair of operations to be able to work with pointers explicitly. But on the other hand, every variable in Python is a pointer, because variables in Python are names that refer to objects.
In Python, our simple example looks like this:
myvar = 17
mypointer = myvar
print(mypointer) # outputs 17
When someone asks, does Python have pointers, perhaps the best answer is: it doesn’t have explicit pointers like some other languages, but everything is implicitly a pointer. So you have the power of pointers to use when you need them: you can have multiple data structures, then assign a variable to one you choose, and use the variable later. You’ve achieved the separation of “which data” from “work with the data” that pointers provide.
Maybe this is yet another case of Same words, different meanings.
Note:
- Some languages like C also allow pointer arithmetic to adjust a pointer from one item in an array to another. Python’s references don’t allow for that.
- Python’s standard library provides ctypes, which is great for interfacing with native C code, exposing details there including C pointers. This does not count as Python having explicit pointers.
Comments
I thought some libraries existed for adding pointers to Python, what about those?
Indeed: https://pypi.org/project/pointers.py - slogan: “Bringing the hell of pointers to python”.
Best used in conjunction with the GOTO (https://pypi.org/project/goto-statement/) library ;-)
Heh. You know the id() function? I wrote a module that added a di() function that would take the supposed-to-be-non-reversible-id()-result and turn it back into a reference to the object.
I did it as a joke. It is a terrible idea, for many obvious reasons.
It seems to have taken on a life of its own:
https://github.com/PythonCHB/di_refcount
I think the power of pointers lies in referring to an object without making a copy. In your Python example, there is a copy of the object because integers are immutable. But putting that object into a list (which is a mutable object) would not involve a copy:
Maybe this would be the equivalent of a pointer in Python?
@DavidBrochart: assignment in Python never makes a copy. Integers especially are not copied, precisely because they are immutable. There’s no reason to copy an integer because they can’t change.
Add a comment: