2.2.6 弱参照(Weak Reference)のサポート

Pythonの弱参照実装のひとつのゴールは、 どのような(数値のような弱参照による利益を得ない)タイプでもオーバーヘッドなしで 弱参照のメカニズムに組み込めるようにすることです。

弱参照可能なオブジェクトの拡張では、弱参照メカニズムのために PyObject*フィールドをインスタンス構造体に含む必要があります。 これはオブジェクトのコンストラクタで NULLに初期化する必要があります。 これは対応するタイプの tp_weaklistoffsetフィールドを フィールドのオフセットに設定しなければいけません。 たとえば、インスタンスタイプは以下の構造体で定義されます:

typedef struct {
    PyObject_HEAD
    PyClassObject *in_class;       /* The class object */
    PyObject      *in_dict;        /* A dictionary */
    PyObject      *in_weakreflist; /* List of weak references */
} PyInstanceObject;

インスタンス用に静的に宣言されたタイプオブジェクトはこのように定義され ます:

PyTypeObject PyInstance_Type = {
    PyObject_HEAD_INIT(&PyType_Type)
    0,
    "module.instance",

    /* Lots of stuff omitted for brevity... */

    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
    0,                                          /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */
};

タイプのコンストラクタは弱参照をNULLに初期化する責任があります:

static PyObject *
instance_new() {
    /* Other initialization stuff omitted for brevity */

    self->in_weakreflist = NULL;

    return (PyObject *) self;
}

さらに、デストラクタは弱参照を消すために弱参照のマネージャを呼ぶ必要があります。 これはデストラクタのどの処理よりも先に実施される必要がありますが、 弱参照リストが NULL でない場合にだけ必要です:

static void
instance_dealloc(PyInstanceObject *inst)
{
    /* Allocate temporaries if needed, but do not begin
       destruction just yet.
     */

    if (inst->in_weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *) inst);

    /* Proceed with object destruction normally. */
}

ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。