You've misunderstood the way that variables work in python - they are just a reference to an object, and reassignment just overwrites the reference with another reference.
As a simplified explanation, imagine that variable assignment works like assigning members of a dictionary. If we call that dictionary variables
, we could rewrite
foo = 5
as
variables["foo"] = 5
Now, you want the current value of variables["foo"]
(if it even exists) to be notified of the assignment, which would mean that the previous statement would become analoguous to the following:
variables["foo"].__somemethod__() #call magic method to notify reassignment
variables["foo"] = 5 # set new value
While you could actually implement this exact behaviour with a dict
subclass, this is simply not the way that variable assignment in CPython is implemented. The object that is referenced by a variable is not in any way notified of the fact that it is not referenced by variables["foo"]
anymore. All that happens is that the reference count of the previously referenced object (if there was any) is decremented by one.
As the answer by Stick demonstrates, there is a __del__
method which is called when the object is garbage collected, which may or may not be enough for your actual use case. But when this is called is actually up to the gc so it can exhibit some funky behaviour; see e.g. this answer for a discussion of some quirks. Furthermore, before python3.4 it was not even guaranteed that any referenced objects are still alive when __del__
is invoked, this has now been fixed: http://legacy.python.org/dev/peps/pep-0442/.
If you really need to be notified of a reference being overwritten (and I'd doubt that there isn't a better way to solve your actual problem), consider using a subclassed or monkeypatched dict
for all references you want to track. You would need to overwrite the __setattr__
method to perform the actions you want to happen when a reference is overwritten.