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);
}
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。