2017-10-08 6 views
1

Pythons optionale Garbage Collector gc ignoriert Zyklen, die contain any object with a __del__ method:Behandelt `gc` Cythons` __dealloc__` ähnlich wie `__del__`?

in Version geändert 3.4: Nach PEP 442 Objekte mit einem __del__() Verfahren nicht mehr in gc.garbage enden.

Cython Erweiterungstypen können eine __dealloc__ Methode, aber no __del__ method:

Hinweis: Es gibt keine __del__() Methode für Erweiterungstypen.

Zum Zweck des Sammelns von Zyklen, wird das Vorhandensein von __dealloc__ vom Garbage Collector behandelt, als ob ein __del__ Verfahren vorhanden ist? Oder ist __dealloc__ unsichtbar für den Garbage Collector?

Antwort

1

Wenn Sie bei dem generierten C-Code können Sie sehen, dass Cython den destructor im tp_dealloc Schlitz erzeugt, anstatt der tp_del Schlitz

cdef class B: 
    def __dealloc__(self): 
     pass 

erzeugt:

static PyTypeObject __pyx_type_5cy_gc_B = { 
    PyVarObject_HEAD_INIT(0, 0) 
    "cy_gc.B", /*tp_name*/ 
    sizeof(struct __pyx_obj_5cy_gc_B), /*tp_basicsize*/ 
    0, /*tp_itemsize*/ 
    __pyx_tp_dealloc_5cy_gc_B, /*tp_dealloc*/ 

    /* lines omitted */ 

    0, /*tp_del*/ 
    0, /*tp_version_tag*/ 
    #if PY_VERSION_HEX >= 0x030400a1 
    0, /*tp_finalize*/ 
    #endif 
}; 

Sie leicht überprüfen können, das ist auch bei anderen Beispielen der Fall (zB Klassen mit automatisch generierten __dealloc__).

Therefore, for Python 3.4+:

mit Python 3.4 starten, sollte diese Liste der meiste Zeit, außer bei der Verwendung von Instanzen von C Erweiterungstypen mit einem nicht-NULL tp_del Slot leer sein.

Cython Klassen sollten nicht in dieser Liste nichteinbringlicher Sachen am Ende, da sie nicht über tp_del definiert.


Für frühere Versionen von Python denke ich, dass es dir auch gut geht. Meistens weil Sie immer noch keine __del__ Methode haben, aber auch weil cython automatically generates tp_traverse and tp_clear functions, die Python erlauben sollte, Referenzzyklen zu unterbrechen, Cython-Klassen beinhalten.

Sie können die Generierung dieser Funktionen tp_traverse und tp_clear deaktivieren. Ich weiß nicht genau, was mit Objekten passiert, die sich in einem Referenzzyklus befinden, aber keine Methoden haben, um sie zu erkennen oder zu brechen. Es ist sehr wahrscheinlich, dass sie irgendwo weiter existieren, aber unzugänglich sind.


denke ich die Sorge (vor Python 3.4) wurde die __del__ Methoden könnten ein Objekt wieder zugänglich machen:

class C: 
    def __del__(self): 
     global x 
     x = self 

__dealloc__ nach dem Punkt ohne Rückkehr genannt, und so ist das nicht erlaubt (Sie erhalten nur einen Segmentierungsfehler, wenn Sie auf x zugreifen).Daher müssen sie nicht in gc.garbage in ihrem unbestimmten Zustand stecken.

Verwandte Themen