Question: I know how to get the value of a variable by its id in Python like:

```
a = "hello world!"
ctypes.cast(id(a), ctypes.py_object).value

```

I wonder if it possible to overwrite the variables value by id?

The simplest way, this one:

```
ctypes.cast(id(a), ctypes.py_object).value = "new value"

```

does not work.

Answer: 
Why it did not work
-------------------

The object `ctypes.cast(id(a), ctypes.py_object)` only provides a view on an object in memory. So when updating the `value` attribute you do not update the object itself, all you do is create a new object and make `value` point to it.

```
import ctypes

a = "Hello World!"
py_obj = ctypes.cast(id(a), ctypes.py_object)

id(py_obj.value) # 1868526529136

py_obj.value = 'Bye Bye World!'

# Here we can see that `value` now points to a new object
id(py_obj.value) # 1868528280112

```

How to mutate any object
------------------------

It is possible, with `ctypes`, to update memory directly and thus to mutate any object. That is even true for strings which are said to be immutable.

The following is interesting as an exercice, but **should never be used** in other circumstances. Among other things it can corrupt object reference count, leading to memory management errors.

```
import ctypes
import sys

def mutate(obj, new_obj):
    if sys.getsizeof(obj) != sys.getsizeof(new_obj):
        raise ValueError('objects must have same size')

    mem = (ctypes.c_byte * sys.getsizeof(obj)).from_address(id(obj))
    new_mem = (ctypes.c_byte * sys.getsizeof(new_obj)).from_address(id(new_obj))

    for i in range(len(mem)):
        mem[i] = new_mem[i]

```

Here are examples. Among these you will find reasons why **you must not use the above code** unless you really know what you are doing or as an exercice.

```
s = 'Hello World!'
mutate(s, 'Bye World!!!')
print(s) # prints: 'Bye World!!!'

# The following happens because of Python interning
mutate('a', 'b')
print('a') # prints: 'b'

mutate(1, 2)
print(1) # prints: 2

```

In particular, the above example makes Python exit with an unknown error code or crash, depending on the version and environment.
`a` is a string, and strings are immutable in Python.

Example from documentation:

```
>>> s = "Hello, World"
>>> c_s = c_wchar_p(s)
>>> print(c_s)
c_wchar_p(139966785747344)
>>> print(c_s.value)
Hello World
>>> c_s.value = "Hi, there"
>>> print(c_s)              # the memory location has changed
c_wchar_p(139966783348904)
>>> print(c_s.value)
Hi, there
>>> print(s)                # first object is unchanged
Hello, World
>>>

```