Simulate Pointers in Python

How can I simulate pointers in Python?

I understand that Python doesn’t have pointers, but I’m looking for a way to achieve something similar to the following behavior:

a = 1
b = a  # How can I modify this line so that b "points to" a?
a = 2
print(b)  # Expected output: 2, but it outputs 1

For example, in PHP, I can have something like this:

class Form {
    public $data = [];
    public $fields;
    
    function __construct($fields) {
        $this->fields = $fields;
        foreach($this->fields as &$field) {
            $this->data[$field['id']] = &$field['value'];
        }
    }
}

$f = new Form([
    ['id' => 'fname', 'value' => 'George'],
    ['id' => 'lname', 'value' => 'Lucas']
]);

echo $f->data['fname'], $f->fields[0]['value']; // George George
$f->data['fname'] = 'Ralph';
echo $f->data['fname'], $f->fields[0]['value']; // Ralph Ralph

Similarly, in C++:

#include <iostream>
using namespace std;

int main() {
    int a;
    int* b = &a;
    a = 1;
    cout << a << endl << *b << endl; // 1 1
    
    return 0;
}

Is there any way to simulate this pointers in Python concept where multiple variables point to the same object, and changes in one reflect in the others?

This is a good starting point! In Python, you can simulate pointers in Python by using mutable data types like lists or dictionaries. These types are passed by reference, so changes in one variable affect the other if they point to the same object. Here’s an example:

a = [1]
b = a  # b "points to" the same list as a
a[0] = 2
print(b[0])  # Output will be 2 because b points to the same list

This works well for scenarios where you want variables to share and reflect changes in a mutable object."

Building on that idea, another way to understand pointers in Python is by checking object references using id(). While Python doesn’t have true pointers like C, it does allow multiple variables to reference the same object, which can achieve similar behavior. For example:

a = 1
b = a  # b references the same object as a
print(id(a), id(b))  # Same IDs, initially

a = 2
print(id(a), id(b))  # Different IDs; a now points to a new object
print(b)  # Output: 1 (b still points to the original object with value 1)

But with mutable objects like lists, the behavior is different:

lst = [1]
b = lst
lst.append(2)
print(b)  # Output: [1, 2] (both point to the same list)

This highlights how object mutability impacts reference behavior in Python.

Great points so far! To take this further, Python’s weakref module can provide more advanced behavior for simulating pointers in Python. It allows you to create references to objects without preventing their garbage collection. Think of it as a lightweight reference mechanism.

Here’s how it works:

import weakref

a = [1]
b = weakref.ref(a)  # b is a weak reference to a
a.append(2)
print(b())  # Output: [1, 2] (b() gives access to the updated object)

# If the original object is deleted:
del a
print(b())  # Output: None (the reference is cleared)

This is particularly useful for managing memory in larger systems or tracking objects without creating strong references. It’s not an exact replica of C-style pointers, but it’s as close as Python gets!