1.10.2 所有権にまつわる規則

オブジェクトへの参照を関数の内外に渡す場合には、オブジェクトの 所有権が参照と共に渡されるか否かが常に関数インタフェース仕様の一部と なります。

オブジェクトへの参照を返すほとんどの関数は、参照とともに所有権も 渡します。特に、PyInt_FromLong()Py_BuildValue() のように、新しいオブジェクトを生成する 関数は全て所有権を相手に渡します。オブジェクトが実際には新たな オブジェクトでなくても、そのオブジェクトに対する新たな参照の 所有権を得ます。例えば、PyInt_FromLong() はよく使う値をキャッシュしており、キャッシュされた値への参照を 返すことがあります。

PyObject_GetAttrString() のように、あるオブジェクトから 別のオブジェクトを抽出するような関数もまた、参照とともに所有権を 委譲します。こちらの方はやや理解しにくいかもしれません。というのは よく使われるルーチンのいくつかが例外となっているからです: PyTuple_GetItem()PyList_GetItem()PyDict_GetItem()、および PyDict_GetItemString() は全て、タプル、リスト、または辞書から借用参照を返します。

PyImport_AddModule() は、実際にはオブジェクトを生成して 返すことがあるにもかかわらず、借用参照を返します: これが可能なのは、 生成されたオブジェクトに対する所有参照はsys.modules に 保持されるからです。

オブジェクトへの参照を別の関数に渡す場合、一般的には、関数側は 呼び出し手から参照を借用します -- 参照を保存する必要があるなら、 関数側はPy_INCREF() を呼び出して独立した所有者に なります。とはいえ、この規則には二つの重要な例外: PyTuple_SetItem()PyList_SetItem() があります。これらの関数は、渡された引数要素に対して所有権を 乗っ取り (take over) ます -- たとえ失敗してもです! (PyDict_SetItem() とその仲間は所有権を乗っ取りません -- これらはいわば ``普通の'' 関数です。)

Python から C 関数が呼び出される際には、C 関数は呼び出し側から 引数への参照を借用します。C 関数の呼び出し側はオブジェクトへの参照を 所有しているので、借用参照の生存期間が保証されるのは関数が処理を 返すまでです。このようにして借用参照を保存したり他に渡したりしたい 場合にのみ、Py_INCREF() を使って所有参照にする必要が あります。

Python から呼び出された C 関数が返す参照は所有参照でなければ なりません -- 所有権は関数から呼び出し側へと委譲されます。

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