2

Firstly, I know object is destruct(or destroyed) when its __del__ function called by gc implicitly or called explicitly. ok, why I could get the object's member variable by its reference after this object was destroyed.

python version is 3.7.1

class O():
    def __init__(self):
        self.name = 'I am a O'
    def __del__(self):
        print('Oops, O is deleted')

if __name__ == '__main__':
    o = O()
    c = o
    print(id(o))
    o.__del__()
    print(c.name)
    print(id(c))

The result

2473601495560
Oops, O is deleted
I am a O
2473601495560
Oops, O is deleted

We could find the problem exists, and the destruct function was called 2 times but why. thanks for help

wanncy
  • 77
  • 7
  • 1
    See https://stackoverflow.com/questions/1481488/what-is-the-del-method-how-to-call-it . `o.__del__` **doesn't** delete `o`, it's just a method that will be called when `o` is destroyed. – Thierry Lathuille Aug 24 '19 at 11:47

1 Answers1

0

First some ground truths.

  • CPython uses reference counting. Objects are de-allocated when their reference count drops to 0.
  • Not all objects are handled by the gc module. From the documentation:

    As a general rule, instances of atomic types aren’t tracked and instances of non-atomic types (containers, user-defined objects…) are.

  • Python "variables" are actually names that reference objects.

So when you do c = o, you create a second reference to the same class O instance that o references. That is why they have the same id.

By definition, when an object is de-allocated, there are no more references to it. So you cannot get a reference to it anymore.

Edit: Your impression of __del__ seems kind of upside-down. It wil generally be called by Python after the reference count has reached 0, see the relevant documentation. But if your program calls an object's __del__ method, that does not magically remove all references! See this answer (and the documentation mentioned before) for the a more detailed explanation.

Double underscore methods (or "dunder" methods) are for Python to use internally to provide some functionality. You should as a rule not call them from your program.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94