Pertanyaan Mengamati kerusakan objek dengan Python dan PyQt dengan __del__


Saya memiliki PyQt QWidget (objek A; itu hanya wadah pasive) yang berisi beberapa widget anak (yaitu ada referensi orangtua-anak Qt'ish). A's child widgets direferensikan dari objek lain (objek B; bukan objek Qt) yang memberi makan anak-anak A dengan data dan benar-benar mengendalikan kreasi dan struktur anak-anak A. Selain anak-anak A, objek B tidak memiliki referensi luar lainnya. Objek A memiliki referensi ke objek B. Jadi, ini adalah contoh buku teks murni dari referensi melingkar.

Saya ingin, pada titik waktu tertentu, menghapus seluruh struktur yang saling berhubungan dari objek A dan B. Saya cukup menelepon A.deleteLater() yang direkomendasikan untuk objek Qt. Sepertinya saya bekerja dengan baik dan menghapus A dan B karena mereka tidak memiliki referensi luar, hanya yang bersama ... tapi masalahnya adalah saya tidak begitu yakin jika itu benar-benar berfungsi, jika itu bisa diandalkan akan bekerja di mana-mana dan jika ada bahaya jika seseorang akan subkelas B misalnya.

Untuk keperluan debugging saya ingin mengamati penghancuran A dan B yang tepat __del__ destructor yang hanya akan mencetak sesuatu seperti A was destroyed. Tapi kemudian saya pelajari di dokumen itu kapan __del__ hadir, pengumpul sampah tidak akan mengumpulkan benda-benda seperti itu dengan referensi melingkar. Apakah ini berarti bahwa mengamati kehancuran akan mempengaruhi atau membatalkan penghancuran? Jika saya benar ini tampaknya menjadi sesuatu seperti mekanika kuantum - keberadaan pengamat yang mempengaruhi hasil eksperimen.

Jadi pada dasarnya ada dua pertanyaan:

  1. apakah ini penggunaan deleteLater() benar dan dapat diandalkan? dan

  2. Apakah pencetakan pesan masuk __del__ destructor mempengaruhi garbage collector? Atau cara lain apa yang bisa saya gunakan untuk mengamati dan mengkonfirmasi kehancuran selama debugging?


4
2017-12-20 13:38


asal


Jawaban:


Salah satu pendekatan yang mungkin adalah menggunakan referensi lemah ke objek, dan kemudian secara berkala memeriksa untuk melihat apakah itu sudah dikumpulkan sampah (atau memaksa pengumpulan sampah). Inilah contoh sederhana:

>>> import weakref
>>> class Object:
...     pass
... 
>>> o = Object()
>>> r = weakref.ref(o)
>>> r()
<__main__.Object instance at 0x10e8c9e18>
>>> del o
>>> r()
<__main__.Object instance at 0x10e8c9e18>
>>> import gc
>>> gc.collect()
0
>>> r()
>>>

0
2017-07-25 22:52