destructor tp_dealloc;
型のインスタンスの参照カウントがゼロになり、 Python インタプリタがそれを潰して再利用したくなると、 この関数が呼ばれます。解放すべきメモリをその型が保持していたり、 それ以外にも実行すべき後処理がある場合は、それらをここに入れます。 オブジェクトそれ自体もここで解放される必要があります。 この関数の例は、以下のようなものです:
static void newdatatype_dealloc(newdatatypeobject * obj) { free(obj->obj_UnderlyingDatatypePtr); obj->ob_type->tp_free(obj); }
解放用関数でひとつ重要なのは、処理待ちの例外にいっさい手をつけないことです。 なぜなら、解放用の関数は Python インタプリタがスタックを元の状態に戻すときに 呼ばれることが多いからです。そして (通常の関数からの復帰でなく) 例外のために スタックが巻き戻されるときは、すでに発生している例外から解放用関数を 守るものはありません。解放用の関数がおこなう動作が追加の Python のコードを 実行してしまうと、それらは例外が発生していることを検知するかもしれません。 これはインタプリタが誤解させるエラーを発生させることにつながります。 これを防ぐ正しい方法は、安全でない操作を実行する前に処理待ちの例外を 保存しておき、終わったらそれを元に戻すことです。これは PyErr_Fetch() および PyErr_Restore() 関数を使うことによって 可能になります:
static void my_dealloc(PyObject *obj) { MyObject *self = (MyObject *) obj; PyObject *cbresult; if (self->my_callback != NULL) { PyObject *err_type, *err_value, *err_traceback; int have_error = PyErr_Occurred() ? 1 : 0; if (have_error) PyErr_Fetch(&err_type, &err_value, &err_traceback); cbresult = PyObject_CallObject(self->my_callback, NULL); if (cbresult == NULL) PyErr_WriteUnraisable(); else Py_DECREF(cbresult); if (have_error) PyErr_Restore(err_type, err_value, err_traceback); Py_DECREF(self->my_callback); } obj->ob_type->tp_free((PyObject*)self); }
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。