型オブジェクト¶
新スタイルの型を定義する構造体: PyTypeObject
構造体は、おそらく Python オブジェクトシステムの中で最も重要な構造体の1つでしょう。型オブジェクトは PyObject_*()
系や PyType_*()
系の関数で扱えますが、ほとんどの Python アプリケーションにとって、さして面白みのある機能を提供しません。型オブジェクトはオブジェクトがどのように振舞うかを決める基盤ですから、インタプリタ自体や新たな型を定義する拡張モジュールでは非常に重要な存在です。
型オブジェクトは標準の型 (standard type) に比べるとかなり大きな構造体です。各型オブジェクトは多くの値を保持しており、そのほとんどは C 関数へのポインタで、それぞれの関数はその型の機能の小さい部分を実装しています。この節では、型オブジェクトの各フィールドについて詳細を説明します。各フィールドは、構造体内で出現する順番に説明されています。
Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, intargfunc, intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, cmpfunc, reprfunc, hashfunc
PyTypeObject
の構造体定義は Include/object.h
で見つけられるはずです。参照の手間を省くために、ここでは定義を繰り返します:
typedef struct _typeobject {
PyObject_VAR_HEAD
const char *tp_name; /* For printing, in format "<module>.<name>" */
Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
/* Methods to implement standard operations */
destructor tp_dealloc;
printfunc tp_print;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
or tp_reserved (Python 3) */
reprfunc tp_repr;
/* Method suites for standard classes */
PyNumberMethods *tp_as_number;
PySequenceMethods *tp_as_sequence;
PyMappingMethods *tp_as_mapping;
/* More standard operations (here for binary compatibility) */
hashfunc tp_hash;
ternaryfunc tp_call;
reprfunc tp_str;
getattrofunc tp_getattro;
setattrofunc tp_setattro;
/* Functions to access object as input/output buffer */
PyBufferProcs *tp_as_buffer;
/* Flags to define presence of optional/expanded features */
unsigned long tp_flags;
const char *tp_doc; /* Documentation string */
/* call function for all accessible objects */
traverseproc tp_traverse;
/* delete references to contained objects */
inquiry tp_clear;
/* rich comparisons */
richcmpfunc tp_richcompare;
/* weak reference enabler */
Py_ssize_t tp_weaklistoffset;
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;
/* Attribute descriptor and subclassing stuff */
struct PyMethodDef *tp_methods;
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
struct _typeobject *tp_base;
PyObject *tp_dict;
descrgetfunc tp_descr_get;
descrsetfunc tp_descr_set;
Py_ssize_t tp_dictoffset;
initproc tp_init;
allocfunc tp_alloc;
newfunc tp_new;
freefunc tp_free; /* Low-level free-memory routine */
inquiry tp_is_gc; /* For PyObject_IS_GC */
PyObject *tp_bases;
PyObject *tp_mro; /* method resolution order */
PyObject *tp_cache;
PyObject *tp_subclasses;
PyObject *tp_weaklist;
destructor tp_del;
/* Type attribute cache version tag. Added in version 2.6 */
unsigned int tp_version_tag;
destructor tp_finalize;
} PyTypeObject;
型オブジェクト構造体は PyVarObject
構造体を拡張したものです。 ob_size
フィールドは、(通常 class 文が呼び出す type_new()
で生成される) 動的な型に使います。 PyType_Type
(メタタイプ) は tp_itemsize
を初期化するので注意してください。すなわち、 インスタンス (つまり型オブジェクト) には ob_size
フィールドが存在しなければ なりません 。
-
PyObject*
PyObject._ob_next
¶ -
PyObject*
PyObject._ob_prev
¶ これらのフィールドはマクロ
Py_TRACE_REFS
が定義されている場合のみ存在します。PyObject_HEAD_INIT
マクロを使うと、フィールドを NULL に初期化します。静的にメモリ確保されているオブジェクトでは、これらのフィールドは常に NULL のままです。動的にメモリ確保されるオブジェクトの場合、これら二つのフィールドは、ヒープ上の 全ての 存続中のオブジェクトからなる二重リンクリストでオブジェクトをリンクする際に使われます。このことは様々なデバッグ目的に利用できます; 現状では、環境変数PYTHONDUMPREFS
が設定されているときに、プログラムの実行終了時点で存続しているオブジェクトを出力するのが唯一の用例です。サブタイプはこのフィールドを継承しません。
-
Py_ssize_t
PyObject.ob_refcnt
¶ 型オブジェクトの参照カウントで、
PyObject_HEAD_INIT
はこの値を1
に初期化します。静的にメモリ確保された型オブジェクトでは、型のインスタンス (ob_type
が該当する型を指しているオブジェクト) は参照をカウントする対象には なりません 。動的にメモリ確保される型オブジェクトの場合、インスタンスは参照カウントの対象に なります 。サブタイプはこのフィールドを継承しません。
-
PyTypeObject*
PyObject.ob_type
¶ 型自体の型、別の言い方をするとメタタイプです。
PyObject_HEAD_INIT
マクロで初期化され、通常は&PyType_Type
になります。しかし、(少なくとも) Windows で利用できる動的ロード可能な拡張モジュールでは、コンパイラは有効な初期化ではないと文句をつけます。そこで、ならわしとして、PyObject_HEAD_INIT
には NULL を渡して初期化しておき、他の操作を行う前にモジュールの初期化関数で明示的にこのフィールドを初期化することになっています。この操作は以下のように行います:Foo_Type.ob_type = &PyType_Type;
上の操作は、該当する型のいかなるインスタンス生成よりも前にしておかなければなりません。
PyType_Ready()
はob_type
が NULL かどうか調べ、 NULL の場合には基底クラスのob_type
フィールドで初期化します。 ob_type フィールドがゼロでない場合、PyType_Ready()
はこのフィールドを変更しません。サブタイプはこのフィールドを継承します。
-
Py_ssize_t
PyVarObject.ob_size
¶ 静的にメモリ確保されている型オブジェクトの場合、このフィールドはゼロに初期化されます。動的にメモリ確保されている型オブジェクトの場合、このフィールドは内部使用される特殊な意味を持ちます。
サブタイプはこのフィールドを継承しません。
-
const char*
PyTypeObject.tp_name
¶ 型の名前が入っている NUL 終端された文字列へのポインタです。モジュールのグローバル変数としてアクセスできる型の場合、この文字列は完全なモジュール名、ドット、そして型の名前と続く文字列になります; 組み込み型の場合、ただの型の名前です。モジュールがあるパッケージのサブモジュールの場合、完全なパッケージ名が完全なモジュール名の一部になっています。例えば、パッケージ
P
内のサブモジュールQ
に入っているモジュールM
内で定義されているT
は、tp_name
を"P.Q.M.T"
に初期化します。動的にメモリ確保される型オブジェクトの場合、このフィールドは単に型の名前になり、モジュール名は型の辞書内でキー
'__module__'
に対する値として明示的に保存されます。静的にメモリ確保される型オブジェクトの場合、 tp_name フィールドにはドットが含まれているはずです。 最後のドットよりも前にある部分文字列全体は
__module__
属性として、またドットよりも後ろにある部分は__name__
属性としてアクセスできます。ドットが入っていない場合、
tp_name
フィールドの内容全てが__name__
属性になり、__module__
属性は (前述のように型の辞書内で明示的にセットしないかぎり) 未定義になります。 このため、その型は pickle 化できないことになります。 さらに、 pydoc が作成するモジュールドキュメントのリストにも載らなくなります。サブタイプはこのフィールドを継承しません。
-
Py_ssize_t
PyTypeObject.tp_basicsize
¶ -
Py_ssize_t
PyTypeObject.tp_itemsize
¶ これらのフィールドは、型インスタンスのバイトサイズを計算できるようにします。
型には二つの種類があります: 固定長インスタンスの型は、
tp_itemsize
フィールドがゼロで、可変長インスタンスの方はtp_itemsize
フィールドが非ゼロの値になります。固定長インスタンスの型の場合、全てのインスタンスは等しくtp_basicsize
で与えられたサイズになります。可変長インスタンスの型の場合、インスタンスには
ob_size
フィールドがなくてはならず、インスタンスのサイズは N をオブジェクトの "長さ" として、tp_basicsize
とtp_itemsize
の N 倍を足したものになります。 N の値は通常、インスタンスのob_size
フィールドに記憶されます。ただし例外がいくつかあります: 例えば、整数では負の値をob_size
に使って、インスタンスの表す値が負であることを示し、 N 自体はabs(ob_size)
になります。また、ob_size
フィールドがあるからといって、必ずしもインスタンスが可変長であることを意味しません (例えば、 リスト型の構造体は固定長のインスタンスになるにもかかわらず、インスタンスにはちゃんと意味を持ったob_size
フィールドがあります)。基本サイズには、
PyObject_HEAD
マクロまたはPyObject_VAR_HEAD
マクロ (インスタンス構造体を宣言するのに使ったどちらかのマクロ) で宣言されているフィールドが入っています。さらに、_ob_prev
および_ob_next
フィールドがある場合、これらのフィールドもサイズに加算されます。従って、tp_basicsize
の正しい初期化値を得るには、インスタンスデータのレイアウトを宣言するのに使う構造体に対してsizeof
演算子を使うしかありません。基本サイズには、GC ヘッダサイズは入っていません。これらのフィールドはサブタイプに別々に継承されます。基底タイプが 0 でない
tp_itemsize
を持っていた場合、基底タイプの実装に依存しますが、一般的にはサブタイプで別の 0 で無い値をtp_itemsize
に設定するのは安全ではありません。アラインメントに関する注釈: 変数の各要素を配置する際に特定のアラインメントが必要となる場合、
tp_basicsize
の値に気をつけなければなりません。例: ある型がdouble
の配列を実装しているとします。tp_itemsize
はsizeof(double)
です。tp_basicsize
がsizeof(double)
(ここではこれをdouble
のアラインメントが要求するサイズと仮定する) の個数分のサイズになるようにするのはプログラマの責任です。
-
destructor
PyTypeObject.tp_dealloc
¶ インスタンスのデストラクタ関数へのポインタです。この関数は (単量子
None
やEllipsis
の場合のように) インスタンスが決してメモリ解放されない型でない限り必ず定義しなければなりません。デストラクタ関数は、参照カウントが新たにゼロになった際に
Py_DECREF()
やPy_XDECREF()
マクロから呼び出されます。呼び出された時点では、インスタンスはまだ存在しますが、インスタンスに対する参照は全くない状態です。デストラクタ関数はインスタンスが保持している全ての参照を解放し、インスタンスが確保している全てのメモリバッファを (バッファの確保時に使った関数に対応するメモリ解放関数を使って) 解放し、最後に (デストラクタ関数の最後の操作として) その型のtp_free
関数を呼び出します。ある型がサブタイプを作成できない (Py_TPFLAGS_BASETYPE
フラグがセットされていない) 場合、tp_free
の代わりにオブジェクトのメモリ解放関数 (deallocator) を直接呼び出してもかまいません。オブジェクトのメモリ解放関数は、インスタンスのメモリ確保を行う際に使った関数に対応したものでなければなりません; インスタンスをPyObject_New()
やPyObject_VarNew()
でメモリ 確保した場合には、通常PyObject_Del()
を使い、PyObject_GC_New()
やPyObject_GC_NewVar()
で確保した場合にはPyObject_GC_Del()
を使います。サブタイプはこのフィールドを継承します。
-
printfunc
PyTypeObject.tp_print
¶ 予約済みのスロットです。 以前は Python 2.x でオブジェクトのフォーマット出力をするのに使われていました。
-
getattrfunc
PyTypeObject.tp_getattr
¶ オプションのポインタで、get-attribute-string を行う関数を指します。
このフィールドは非推奨です。 このフィールドを定義するときは、
tp_getattro
関数と同じように動作し、属性名は Python 文字列 オブジェクトではなく C 文字列で指定するような関数を指すようにしなければなりません。 シグネチャは次の通りです:PyObject * tp_getattr(PyObject *o, char *attr_name);
このフィールドは
tp_getattro
と共にサブタイプに継承されます: すなわち、サブタイプのtp_getattr
およびtp_getattro
が共に NULL の場合、サブタイプは基底タイプからtp_getattr
とtp_getattro
を両方とも継承します。
-
setattrfunc
PyTypeObject.tp_setattr
¶ オプションのポインタで、属性の設定と削除を行う関数を指します。
このフィールドは非推奨です。 このフィールドを定義するときは、
tp_setattro
関数と同じように動作し、属性名は Python 文字列 オブジェクトではなく C 文字列で指定するような関数を指すようにしなければなりません。 シグネチャは次の通りです:PyObject * tp_setattr(PyObject *o, char *attr_name, PyObject *v);
引数 v に NULL を設定すると属性を削除します。 このフィールドは
tp_setattro
と共にサブタイプに継承されます: すなわち、サブタイプのtp_setattr
およびtp_setattro
が両方とも NULL のとき、サブタイプは基底タイプからtp_setattr
とtp_setattro
を両方とも継承します。
-
PyAsyncMethods*
tp_as_async
¶ 追加の構造体を指すポインタです。 この構造体は、 C レベルで awaitable プロトコルと asynchronous iterator プロトコルを実装するオブジェクトだけに関係するフィールドを持ちます。 詳しいことは async オブジェクト構造体 を参照してください。
バージョン 3.5 で追加: 以前は
tp_compare
やtp_reserved
として知られていました。
-
reprfunc
PyTypeObject.tp_repr
¶ オプションのポインタで、組み込み関数
repr()
を実装している関数を指します。シグネチャは
PyObject_Repr()
と同じです。この関数は文字列オブジェクトか Unicode オブジェクトを返さなければなりません。理想的には、この関数が返す文字列は、適切な環境でeval()
に渡した場合、同じ値を持つオブジェクトになるような文字列でなければなりません。不可能な場合には、オブジェクトの型と値から導出した内容の入った'<'
から始まって'>'
で終わる文字列を返さなければなりません。このフィールドが設定されていない場合、
<%s object at %p>
の形式をとる文字列が返されます。%s
は型の名前に、%p
はオブジェクトのメモリアドレスに置き換えられます。サブタイプはこのフィールドを継承します。
-
PyNumberMethods*
tp_as_number
¶ 数値プロトコルを実装した追加の構造体を指すポインタです。これらのフィールドについては 数値オブジェクト構造体 で説明されています。
tp_as_number
フィールドは継承されませんが、そこの含まれるフィールドが個別に継承されます。
-
PySequenceMethods*
tp_as_sequence
¶ シーケンスプロトコルを実装した追加の構造体を指すポインタです。これらのフィールドについては シーケンスオブジェクト構造体 で説明されています。
tp_as_sequence
フィールドは継承されませんが、これに含まれるフィールドが個別に継承されます。
-
PyMappingMethods*
tp_as_mapping
¶ マッピングプロトコルを実装した追加の構造体を指すポインタです。これらのフィールドについては マップオブジェクト構造体 で説明されています。
tp_as_mapping
フィールドは継承されませんが、これに含まれるフィールドが個別に継承されます。
-
hashfunc
PyTypeObject.tp_hash
¶ オプションのポインタで、組み込み関数
hash()
を実装している関数を指します。シグネチャは
PyObject_Hash()
と同じです。この関数は型 Py_hash_t の値を返さなければなりません。通常時には-1
を戻り値にしてはなりません; ハッシュ値の計算中にエラーが生じた場合、関数は例外をセットして-1
を返さなければなりません。このフィールドは明示的に
PyObject_HashNotImplemented()
に設定することで、親 type からのハッシュメソッドの継承をブロックすることができます。これは Python レベルでの__hash__ = None
と同等に解釈され、isinstance(o, collections.Hashable)
が正しくFalse
を返すようになります。逆もまた可能であることに注意してください - Python レベルで__hash__ = None
を設定することでtp_hash
スロットはPyObject_HashNotImplemented()
に設定されます。このフィールドがセットされていないときに、オブジェクトのハッシュ値を取ろうとすると
TypeError
が送出されます。このフィールドは
tp_richcompare
と共にサブタイプに継承されます: すなわち、サブタイプのtp_richcompare
およびtp_hash
が両方とも NULL のとき、サブタイプは基底タイプからtp_richcompare
とtp_hash
を両方とも継承します。
-
ternaryfunc
PyTypeObject.tp_call
¶ オプションのポインタで、オブジェクトの呼び出しを実装している関数を指します。オブジェクトが呼び出し可能でない場合には NULL にしなければなりません。シグネチャは
PyObject_Call()
と同じです。サブタイプはこのフィールドを継承します。
-
reprfunc
PyTypeObject.tp_str
¶ オプションのポインタで、組み込みの演算
str()
を実装している関数を指します。(str
が型の一つになったため、str()
はstr
のコンストラクタを呼び出すことに注意してください。このコンストラクタは実際の処理を行う上でPyObject_Str()
を呼び出し、さらにPyObject_Str()
がこのハンドラを呼び出すことになります。)シグネチャは
PyObject_Str()
と同じです; この関数は文字列オブジェクトか Unicode オブジェクトを返さなければなりません。また、この関数はオブジェクトを "分かりやすく (friendly)" 表現した文字列を返さなければなりません。というのは、この文字列はとりわけprint()
関数で使われることになる表記だからです。このフィールドが設定されていない場合、文字列表現を返すためには
PyObject_Repr()
が呼び出されます。サブタイプはこのフィールドを継承します。
-
getattrofunc
PyTypeObject.tp_getattro
¶ オプションのポインタで、get-attribute を実装している関数を指します。
シグネチャは
PyObject_GetAttr()
と同じです。 通常の属性検索を実装しているPyObject_GenericGetAttr()
をこのフィールドに設定しておくとたいていの場合は便利です。このフィールドは
tp_getattr
と共にサブタイプに継承されます: すなわち、サブタイプのtp_getattr
およびtp_getattro
が共に NULL の場合、サブタイプは基底タイプからtp_getattr
とtp_getattro
を両方とも継承します。
-
setattrofunc
PyTypeObject.tp_setattro
¶ オプションのポインタで、属性の設定と削除を行う関数を指します。
シグネチャは
PyObject_SetAttr()
と同じですが、 v に NULL を指定して属性を削除できるようにしなければなりません。 通常の属性設定を実装しているPyObject_GenericSetAttr()
をこのフィールドに設定しておくとたいていの場合は便利です。このフィールドは
tp_setattr
と共にサブタイプに継承されます: すなわち、サブタイプのtp_setattr
およびtp_setattro
が共に NULL の場合、サブタイプは基底タイプからtp_setattr
とtp_setattro
を両方とも継承します。
-
PyBufferProcs*
PyTypeObject.tp_as_buffer
¶ バッファインタフェースを実装しているオブジェクトにのみ関連する、一連のフィールド群が入った別の構造体を指すポインタです。構造体内の各フィールドは バッファオブジェクト構造体 (buffer object structure) で説明します。
tp_as_buffer
フィールド自体は継承されませんが、これに含まれるフィールドは個別に継承されます。
-
unsigned long
PyTypeObject.tp_flags
¶ このフィールドは様々なフラグからなるビットマスクです。いくつかのフラグは、特定の状況において変則的なセマンティクスが適用されることを示します; その他のフラグは、型オブジェクト (あるいは
tp_as_number
、tp_as_sequence
、tp_as_mapping
、 およびtp_as_buffer
が参照している拡張機能構造体) の特定のフィールドのうち、過去から現在までずっと存在していたわけではないものが有効になっていることを示すために使われます; フラグビットがクリアされていれば、フラグが保護しているフィールドにはアクセスしない代わりに、その値はゼロか NULL になっているとみなさなければなりません。このフィールドの継承は込み入っています。ほとんどのフラグは個別に継承されます。すなわち、基底タイプのフラグビットが設定されていたら、サブタイプのフラグビットもそれを引き継ぎます。拡張機能構造体が継承される場合は、拡張機能構造体に関係するフラグビットは厳密に継承されます。すなわち、基底タイプのフラグビットの値は、拡張機能構造体へのポインタと共に、サブタイプにコピーされます。
Py_TPFLAGS_HAVE_GC
フラグビットはtp_traverse
フィールドとtp_clear
フィールドと共に継承されます。すなわち、サブタイプにおいて、Py_TPFLAGS_HAVE_GC
フラグビットがクリアされていて、tp_traverse
フィールドとtp_clear
フィールドが存在し NULL になっている場合に継承されます。以下に挙げるビットマスクは現在定義されているものです; フラグは
|
演算子で論理和を取ってtp_flags
フィールドの値を作成できます。PyType_HasFeature()
マクロは型とフラグ値、 tp および f をとり、tp->tp_flags & f
が非ゼロかどうか調べます。-
Py_TPFLAGS_HEAPTYPE
¶ 型オブジェクト自体がヒープにメモリ確保される場合にセットされるビットです。型オブジェクト自体がヒープにメモリ確保される場合、インスタンスの
ob_type
フィールドは型オブジェクトへの参照とみなされます。この場合、新たなインスタンスを生成する度に型オブジェクトを INCREF し、インスタンスを解放するたびに DECREF します (サブタイプのインスタンスには適用されません; インスタンスがob_type
で参照している型だけが INCREF および DECREF されます)。
-
Py_TPFLAGS_BASETYPE
¶ 型を別の型の基底タイプとして使える場合にセットされるビットです。このビットがクリアならば、この型のサブタイプは生成できません (Java における "final" クラスに似たクラスになります)。
-
Py_TPFLAGS_READY
¶ 型オブジェクトが
PyType_Ready()
で完全に初期化されるとセットされるビットです。
-
Py_TPFLAGS_READYING
¶ PyType_Ready()
による型オブジェクトの初期化処理中にセットされるビットです。
-
Py_TPFLAGS_HAVE_GC
¶ オブジェクトがガベージコレクション (GC) をサポートする場合にセットされるビットです。このビットがセットされている場合、インスタンスは
PyObject_GC_New()
を使って生成し、PyObject_GC_Del()
を使って破棄しなければなりません。詳しい情報は 循環参照ガベージコレクションをサポートする にあります。このビットは、GC に関連するフィールドtp_traverse
およびtp_clear
が型オブジェクト内に存在することも示しています。
-
Py_TPFLAGS_DEFAULT
¶ 型オブジェクトおよび拡張機能構造体の特定のフィールドの存在の有無に関連する全てのビットからなるビットマスクです。現状では、このビットマスクには以下のビット:
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION
およびPy_TPFLAGS_HAVE_VERSION_TAG
が入っています。
-
Py_TPFLAGS_LONG_SUBCLASS
¶
-
Py_TPFLAGS_LIST_SUBCLASS
¶
-
Py_TPFLAGS_TUPLE_SUBCLASS
¶
-
Py_TPFLAGS_BYTES_SUBCLASS
¶
-
Py_TPFLAGS_UNICODE_SUBCLASS
¶
-
Py_TPFLAGS_DICT_SUBCLASS
¶
-
Py_TPFLAGS_BASE_EXC_SUBCLASS
¶
-
Py_TPFLAGS_TYPE_SUBCLASS
¶ これらのフラグは
PyLong_Check()
のような関数が、型がとある組み込み型のサブクラスかどうかを素早く判断するのに使われます; この専用のチェックはPyObject_IsInstance()
のような汎用的なチェックよりも高速です。 組み込み型を継承した独自の型ではtp_flags
を適切に設定すべきで、そうしないとその型が関わるコードでは、どんなチェックの方法が使われるかによって振る舞いが異なってしまうでしょう。
-
Py_TPFLAGS_HAVE_FINALIZE
¶ 型構造体に
tp_finalize
スロットが存在しているときにセットされるビットです。バージョン 3.4 で追加.
-
-
const char*
PyTypeObject.tp_doc
¶ オプションのポインタで、この型オブジェクトの docstring を与える NUL 終端された C の文字列を指します。この値は型オブジェクトと型のインスタンスにおける
__doc__
属性として公開されます。サブタイプはこのフィールドを継承 しません 。
-
traverseproc
PyTypeObject.tp_traverse
¶ オプションのポインタで、ガベージコレクタのためのトラバーサル関数 (traversal function) を指します。
Py_TPFLAGS_HAVE_GC
がセットされている場合にのみ使われます。Pythonのガベージコレクションの枠組みに関する詳細は 循環参照ガベージコレクションをサポートする にあります。tp_traverse
ポインタは、ガベージコレクタが循環参照を見つけるために使われます。tp_traverse
関数の典型的な実装は、インスタンスの Pythonオブジェクトである各メンバに対してPy_VISIT()
を呼び出します。例えば、次のコードは_thread
拡張モジュールのlocal_traverse()
関数です:static int local_traverse(localobject *self, visitproc visit, void *arg) { Py_VISIT(self->args); Py_VISIT(self->kw); Py_VISIT(self->dict); return 0; }
Py_VISIT()
が循環参照になる恐れのあるメンバにだけ呼び出されていることに注目してください。self->key
メンバもありますが、それは NULL か Python文字列なので、循環参照の一部になることはありません。一方、メンバが循環参照の一部になり得ないと判っていても、デバッグ目的で巡回したい場合があるかもしれないので、
gc
モジュールのget_referents()
関数は循環参照になり得ないメンバも返します。Py_VISIT()
はlocal_traverse()
が visit と arg という決まった名前の引数を持つことを要求します。このフィールドは
tp_clear
およびPy_TPFLAGS_HAVE_GC
フラグビットと共にサブタイプに継承されます: すなわち、サブタイプのtp_traverse
およびtp_clear
が両方ともゼロの場合、サブタイプは基底タイプからtp_traverse
とtp_clear
を両方とも継承します。
-
inquiry
PyTypeObject.tp_clear
¶ オプションのポインタで、ガベージコレクタにおける消去関数 (clear function) を指します。
Py_TPFLAGS_HAVE_GC
がセットされている場合にのみ使われます。tp_clear
メンバ関数は GC が検出した循環しているゴミの循環参照を壊すために用いられます。総合的な視点で考えると、システム内の全てのtp_clear
関数が連携して、全ての循環参照を破壊しなければなりません。 (訳注: ある型がtp_clear
を実装しなくても全ての循環参照が破壊できるのであれば実装しなくても良い) これはとても繊細で、もし少しでも不確かな部分があるのであれば、tp_clear
関数を提供するべきです。例えば、タプルはtp_clear
を実装しません。なぜなら、タプルだけで構成された循環参照がみつかることは無いからです。従って、タプル以外の型のtp_clear
関数だけで、タプルを含むどんな循環参照も必ず破壊できることになります。これは簡単に判ることではなく、tp_clear
の実装を避ける良い理由はめったにありません。次の例にあるように、
tp_clear
の実装は、インスタンスから Python オブジェクトだと思われるメンバへの参照を外し、それらのメンバへのポインタに NULL をセットすべきです:static int local_clear(localobject *self) { Py_CLEAR(self->key); Py_CLEAR(self->args); Py_CLEAR(self->kw); Py_CLEAR(self->dict); return 0; }
参照のクリアはデリケートなので、
Py_CLEAR()
マクロを使うべきです: ポインタを NULL にセットするまで、そのオブジェクトの参照カウントをデクリメントしてはいけません。参照カウントのデクリメントすると、そのオブジェクトが破棄されるかもしれず、 (そのオブジェクトに関連付けられたファイナライザ、弱参照のコールバックにより) 任意のPythonコードの実行を含む後片付け処理が実行されるかもしれないからです。もしそういったコードが再び self を参照することがあれば、すでに持っていたオブジェクトへのポインタは NULL になっているので、 self は所有していたオブジェクトをもう利用できないことを認識できます。Py_CLEAR()
マクロはその手続きを安全な順番で実行します。tp_clear
関数の目的は参照カウントを破壊することなので、 Python 文字列や Python 整数のような、循環参照に含むことのできないオブジェクトをクリアする必要はありません。一方、所有する全ての Python オブジェクトをクリアするようにし、その型のtp_dealloc
関数がtp_clear
関数を実行するようにすると実装が楽になるでしょう。Pythonのガベージコレクションの仕組みについての詳細は、 循環参照ガベージコレクションをサポートする にあります。
このフィールドは
tp_traverse
およびPy_TPFLAGS_HAVE_GC
フラグビットと共にサブタイプに継承されます: すなわち、サブタイプのtp_traverse
およびtp_clear
が両方ともゼロの場合、サブタイプは基底タイプからtp_traverse
とtp_clear
を両方とも継承します。
-
richcmpfunc
PyTypeObject.tp_richcompare
¶ オプションのポインタで、
PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)
というシグネチャを持つ拡張比較関数を指します。 1つ目の引数は、PyTypeObject
で定義された型のインスタンスであることが保証されています。この関数は、比較結果を返すべきです。(普通は
Py_True
かPy_False
です。) 比較が未定義の場合は、Py_NotImplemented
を、それ以外のエラーが発生した場合には例外状態をセットしてNULL
を返さなければなりません。注釈
限られた種類の比較だけが可能 (例えば、
==
と!=
が可能で<
などが不可能) な型を実装したい場合、拡張比較関数で直接TypeError
を返します。このフィールドは
tp_hash
と共にサブタイプに継承されます: すなわち、サブタイプのtp_richcompare
およびtp_hash
が両方とも NULL のとき、サブタイプは基底タイプからtp_richcompare
とtp_hash
を両方とも継承します。tp_richcompare
およびPyObject_RichCompare()
関数の第三引数に使うための定数としては以下が定義されています:定数 比較 Py_LT
<
Py_LE
<=
Py_EQ
==
Py_NE
!=
Py_GT
>
Py_GE
>=
-
Py_ssize_t
PyTypeObject.tp_weaklistoffset
¶ 型のインスタンスが弱参照可能な場合、このフィールドはゼロよりも大きな数になり、インスタンス構造体における弱参照リストの先頭を示すオフセットが入ります (GC ヘッダがある場合には無視します); このオフセット値は
PyObject_ClearWeakRefs()
およびPyWeakref_*()
関数が利用します。インスタンス構造体には、 NULL に初期化されたPyObject*
型のフィールドが入っていなければなりません。このフィールドを
tp_weaklist
と混同しないようにしてください; これは型オブジェクト自身への弱参照からなるリストの先頭です。このフィールドはサブタイプに継承されますが、以下の規則を読んでください。サブタイプはこのオフセット値をオーバライドすることがあります; 従って、サブタイプでは弱参照リストの先頭が基底タイプとは異なる場合があります。リストの先頭は常に
tp_weaklistoffset
で分かるはずなので、このことは問題にはならないはずです。class
文で定義された型に__slots__
宣言が全くなく、かつ基底タイプが弱参照可能でない場合、その型を弱参照可能にするには弱参照リストの先頭を表すスロットをインスタンスデータレイアウト構造体に追加し、スロットのオフセットをtp_weaklistoffset
に設定します。型の
__slots__
の宣言に__weakref__
という名前のスロットが含まれているとき、スロットはその型のインスタンスにおける弱参照リストの先頭を表すスロットになり、スロットのオフセットが型のtp_weaklistoffset
に入ります。型の
__slots__
宣言が__weakref__
という名前のスロットを含んでいないとき、その型は基底タイプからtp_weaklistoffset
を継承します。
-
getiterfunc
PyTypeObject.tp_iter
¶ オプションの変数で、そのオブジェクトのイテレータを返す関数へのポインタです。この値が存在することは、通常この型のインスタンスがイテレート可能であることを示しています (しかし、シーケンスはこの関数がなくてもイテレート可能です)。
この関数は
PyObject_GetIter()
と同じシグネチャを持っています。サブタイプはこのフィールドを継承します。
-
iternextfunc
PyTypeObject.tp_iternext
¶ オプションのポインタで、イテレータにおいて次の要素を返す関数を指します。イテレータの要素がなくなると、この関数は NULL を返さなければなりません。
StopIteration
例外は設定してもしなくても良いです。その他のエラーが発生したときも、 NULL を返さなければなりません。このフィールドがあると、この型のインスタンスがイテレータであることを示します。イテレータ型では、
tp_iter
関数も定義されていなければならず、その関数は (新たなイテレータインスタンスではなく) イテレータインスタンス自体を返さねばなりません。この関数のシグネチャは
PyIter_Next()
と同じです。サブタイプはこのフィールドを継承します。
-
struct PyMethodDef*
PyTypeObject.tp_methods
¶ オプションのポインタで、この型の正規 (regular) のメソッドを宣言している
PyMethodDef
構造体からなる、 NULL で終端された静的な配列を指します。配列の各要素ごとに、メソッドデスクリプタの入った、要素が型の辞書 (下記の
tp_dict
参照) に追加されます。サブタイプはこのフィールドを継承しません (メソッドは別個のメカニズムで継承されています)。
-
struct PyMemberDef*
PyTypeObject.tp_members
¶ オプションのポインタで、型の正規 (regular) のデータメンバ (フィールドおよびスロット) を宣言している
PyMemberDef
構造体からなる、 NULL で終端された静的な配列を指します。配列の各要素ごとに、メンバデスクリプタの入った要素が型の辞書 (下記の
tp_dict
参照) に追加されます。サブタイプはこのフィールドを継承しません (メンバは別個のメカニズムで継承されています)。
-
struct PyGetSetDef*
PyTypeObject.tp_getset
¶ オプションのポインタで、インスタンスの算出属性 (computed attribute) を宣言している
PyGetSetDef
構造体からなる、 NULL で終端された静的な配列を指します。配列の各要素ごとに、 getter/setter デスクリプタの入った、要素が型の辞書 (下記の
tp_dict
参照) に追加されます。サブタイプはこのフィールドを継承しません (算出属性は別個のメカニズムで継承されています)。
-
PyTypeObject*
PyTypeObject.tp_base
¶ オプションのポインタで、型に関するプロパティを継承する基底タイプを指します。このフィールドのレベルでは、単継承 (single inheritance) だけがサポートされています; 多重継承はメタタイプの呼び出しによる動的な型オブジェクトの生成を必要とします。
(当たり前ですが) サブタイプはこのフィールドを継承しません。しかし、このフィールドのデフォルト値は (Python プログラマは
object
型として知っている)&PyBaseObject_Type
になります。
-
PyObject*
PyTypeObject.tp_dict
¶ 型の辞書は
PyType_Ready()
によってこのフィールドに収められます。このフィールドは通常、
PyType_Ready()
を呼び出す前に NULL に初期化しておかなければなりません; あるいは、型の初期属性の入った辞書で初期化しておいてもかまいません。PyType_Ready()
が型をひとたび初期化すると、型の新たな属性をこの辞書に追加できるのは、属性が (__add__()
のような) オーバロード用演算でないときだけです。サブタイプはこのフィールドを継承しません (が、この辞書内で定義されている属性は異なるメカニズムで継承されます)。
警告
tp_dict
にPyDict_SetItem()
を使ったり、辞書 C-API で編集するのは安全ではありません。
-
descrgetfunc
PyTypeObject.tp_descr_get
¶ オプションのポインタで、デスクリプタの get 関数を指します。
関数のシグネチャは次のとおりです
PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);
サブタイプはこのフィールドを継承します。
-
descrsetfunc
PyTypeObject.tp_descr_set
¶ オプションのポインタで、デスクリプタの値の設定と削除を行う関数を指します。
関数のシグネチャは次のとおりです
int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);
value 引数に NULL を設定して値を消します。 このフィールドはサブタイプに継承されます。
-
Py_ssize_t
PyTypeObject.tp_dictoffset
¶ 型のインスタンスにインスタンス変数の入った辞書がある場合、このフィールドは非ゼロの値になり、型のインスタンスデータ構造体におけるインスタンス変数辞書へのオフセットが入ります; このオフセット値は
PyObject_GenericGetAttr()
が使います。このフィールドを
tp_dict
と混同しないようにしてください; これは型オブジェクト自身の属性の辞書です。このフィールドの値がゼロより大きければ、値はインスタンス構造体の先頭からの オフセットを表します。値がゼロより小さければ、インスタンス構造体の 末尾 からのオフセットを表します。負のオフセットを使うコストは比較的高くつくので、 インスタンス構造体に可変長部分があるときのみ使うべきです。例えば、
str
やtuple
のサブタイプにインスタンス変数の辞書を追加する場合には、負のオフセットを使います。この場合、たとえ辞書が基本のオブジェクトレイアウトに含まれていなくても、tp_basicsize
フィールドは追加された辞書を考慮にいれなければならないことに注意してください。ポインタサイズが 4 バイトのシステムでは、 構造体の最後尾に辞書が宣言されていることを示す場合、tp_dictoffset
を-4
にしなければなりません。負の
tp_dictoffset
から、インスタンスでの実際のオフセットを計算するには以下のようにします:dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset if dictoffset is not aligned on sizeof(void*): round up to sizeof(void*)
ここで、
tp_basicsize
、tp_itemsize
およびtp_dictoffset
は型オブジェクトから取り出され、ob_size
はインスタンスから取り出されます。 絶対値を取っているのは、整数は符号を記憶するのにob_size
の符号を使うためです。 (この計算を自分で行う必要はまったくありません; 計算は_PyObject_GetDictPtr()
がやってくれます。)このフィールドはサブタイプに継承されますが、以下の規則を読んでください。サブタイプはこのオフセット値をオーバライドすることがあります; 従って、サブタイプでは辞書のオフセットが基底タイプとは異なる場合があります。辞書のオフセットは常に
tp_dictoffset
で分かるはずなので、このことは問題にはならないはずです。class
文で定義された型に__slots__
宣言がなく、かつ基底タイプの全てにインスタンス変数辞書がない場合、辞書のスロットをインスタンスデータレイアウト構造体に追加し、スロットのオフセットをtp_dictoffset
に設定します。class
文で定義された型に__slots__
宣言がある場合、この型は基底タイプからtp_dictoffset
を継承します。(
__dict__
という名前のスロットを__slots__
宣言に追加しても、期待どおりの効果は得られず、単に混乱を招くだけになります。とはいえ、これは将来__weakref__
のように追加されるはずです。)
-
initproc
PyTypeObject.tp_init
¶ オプションのポインタで、インスタンス初期化関数を指します。
この関数はクラスにおける
__init__()
メソッドに対応します。__init__()
と同様、__init__()
を呼び出さずにインスタンスを作成できます。また、__init__()
を再度呼び出してインスタンスの再初期化もできます。関数のシグネチャは次のとおりです
int tp_init(PyObject *self, PyObject *args, PyObject *kwds)
self 引数は初期化するインスタンスです; args および kwds 引数は、
__init__()
を呼び出す際の位置引数およびキーワード引数です。tp_init
関数のフィールドが NULL でない場合、通常の型を呼び出す方法のインスタンス生成において、型のtp_new
関数がインスタンスを返した後に呼び出されます。tp_new
が元の型のサブタイプでない別の型を返す場合、tp_init
は全く呼び出されません;tp_new
が元の型のサブタイプのインスタンスを返す場合、サブタイプのtp_init
が呼び出されます。サブタイプはこのフィールドを継承します。
-
allocfunc
PyTypeObject.tp_alloc
¶ オプションのポインタで、インスタンスのメモリ確保関数を指します。
関数のシグネチャは次のとおりです
PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems)
この関数の目的は、メモリ確保をメモリ初期化から分離することにあります。この関数は、インスタンス用の的確なサイズ、適切なアラインメント、ゼロによる初期化がなされ、
ob_refcnt
を1
に、ob_type
を型引数 (type argument) にセットしたメモリブロックへのポインタを返さねばなりません。型のtp_itemsize
がゼロでない場合、オブジェクトのob_size
フィールドは nitems に初期化され、確保されるメモリブロックの長さはtp_basicsize + nitems*tp_itemsize
をsizeof(void*)
の倍数に切り上げた値になるはずです; それ以外の場合、 nitems の値は使われず、メモリブロックの長さはtp_basicsize
になるはずです。この関数をインスタンス初期化の他のどの処理にも、追加でメモリ確保をする場合でさえ使ってはなりません; そうした処理は
tp_new
で行わねばなりません。静的なサブタイプはこのフィールドを継承しますが、動的なサブタイプ (
class
文で生成するサブタイプ) の場合は継承しません; 後者の場合、このフィールドは常にPyType_GenericAlloc()
にセットされ、標準のヒープ上メモリ確保戦略が強制されます。静的に定義する型の場合でも、PyType_GenericAlloc()
を推奨します。
-
newfunc
PyTypeObject.tp_new
¶ オプションのポインタで、インスタンス生成関数を指します。
このフィールドが NULL を指している型では、型を呼び出して新たなインスタンスを生成できません; こうした型では、おそらくファクトリ関数のように、インスタンスを生成する他の方法があるはずです。
関数のシグネチャは次のとおりです
PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
subtype 引数は生成するオブジェクトの型です; args および kwds 引数は、型を呼び出すときの位置引数およびキーワード引数です。サブタイプは
tp_new
関数を呼び出すときに使う型と同じである必要はないことに注意してください; その型の (無関係ではない) サブタイプのこともあります。tp_new
関数はsubtype->tp_alloc(subtype, nitems)
を呼び出してオブジェクトのメモリ領域を確保し、初期化で絶対に必要とされる処理だけを行います。省略したり繰り返したりしても問題のない初期化処理はtp_init
ハンドラ内に配置しなければなりません。だいたいの目安としては、変更不能な型では初期化は全てtp_new
で行い、一方、変更可能な型ではほとんどの初期化をtp_init
に回すべきです。サブタイプはこのフィールドを継承します。例外として、
tp_base
が NULL か&PyBaseObject_Type
になっている静的な型では継承しません。
-
destructor
PyTypeObject.tp_free
¶ インスタンスのメモリ解放関数を指す、オプションのポインタです。シグネチャは
freefunc
です:void tp_free(void *)
このシグネチャと互換性のある初期化子は
PyObject_Free()
です。静的なサブタイプはこのフィールドを継承しますが、動的なサブタイプ (
class
文で生成するサブタイプ) の場合は継承しません; 後者の場合、このフィールドにはPyType_GenericAlloc()
とPy_TPFLAGS_HAVE_GC
フラグビットの値に対応させるのにふさわしいメモリ解放関数がセットされます。
-
inquiry
PyTypeObject.tp_is_gc
¶ オプションのポインタで、ガベージコレクタから呼び出される関数を指します。
ガベージコレクタは、オブジェクトを回収して良いかどうかを知る必要があります。通常は、オブジェクトの型の
tp_flags
フィールドを見て、Py_TPFLAGS_HAVE_GC
フラグビットを調べるだけで十分です。しかし、ある型では静的にメモリ確保されたインスタンスと動的にメモリ確保されたインスタンスが混じっていて、静的にメモリ確保されたインスタンスは回収できません。こうした型では、関数を定義しなければなりません; 関数はインスタンスが回収可能の場合には1
を、回収不能の場合には0
を返さねばなりません。シグネチャはint tp_is_gc(PyObject *self)
(上記のような型の例は、型オブジェクト自体です。メタタイプ
PyType_Type
は、型のメモリ確保が静的か動的かを区別するためにこの関数を定義しています。)サブタイプはこのフィールドを継承します。
-
PyObject*
PyTypeObject.tp_bases
¶ 基底型からなるタプルです。
class
文で生成されたクラスの場合このフィールドがセットされます。静的に定義されている型の場合には、このフィールドは NULL になります。このフィールドは継承されません。
-
PyObject*
PyTypeObject.tp_mro
¶ 基底タイプ群を展開した集合が入っているタプルです。集合は該当する型自体からはじまり、
object
で終わります。メソッド解決順序 (Method Resolution Order) に従って並んでいます。このフィールドは継承されません; フィールドの値は
PyType_Ready()
で毎回計算されます。
-
destructor
PyTypeObject.tp_finalize
¶ オプションのポインタで、インスタンスの終了処理関数を指します。 シグネチャは
destructor
です:void tp_finalize(PyObject *)
tp_finalize
が設定されている場合、インスタンスをファイナライズするときに、インタプリタがこの関数を1回呼び出します。 ガベージコレクタ (このインスタンスが孤立した循環参照の一部だった場合) やオブジェクトが破棄される直前にもこの関数は呼び出されます。 どちらの場合でも、循環参照を破壊しようとする前に呼び出されることが保証されていて、確実にオブジェクトが正常な状態にあるようにします。tp_finalize
は現在の例外状態を変更すべきではありません; 従って、単純でないファイナライザを書くには次の方法が推奨されます:static void local_finalize(PyObject *self) { PyObject *error_type, *error_value, *error_traceback; /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); /* ... */ /* Restore the saved exception. */ PyErr_Restore(error_type, error_value, error_traceback); }
このフィールドを (継承した場合も含めて) 考慮から漏らさないように、
Py_TPFLAGS_HAVE_FINALIZE
フラグビットも設定しなければなりません。サブタイプはこのフィールドを継承します。
バージョン 3.4 で追加.
参考
"オブジェクトの安全な終了処理" (PEP 442)
残りのフィールドは、機能テスト用のマクロである COUNT_ALLOCS
が定義されている場合のみ利用でき、内部で使用するためだけのものです。これらのフィールドについて記述するのは単に完全性のためです。サブタイプはこれらのフィールドを継承しません。
-
Py_ssize_t
PyTypeObject.tp_allocs
¶ メモリ確保の回数です。
-
Py_ssize_t
PyTypeObject.tp_frees
¶ メモリ解放の回数です。
-
Py_ssize_t
PyTypeObject.tp_maxalloc
¶ 同時にメモリ確保できる最大オブジェクト数です。
-
PyTypeObject*
PyTypeObject.tp_next
¶ 次のゼロでない
tp_allocs
フィールドを持つ型オブジェクトへのポインタです。
また、 Python のガベージコレクションでは、 tp_dealloc を呼び出すのはオブジェクトを生成したスレッドだけではなく、任意の Python スレッドかもしれないという点にも注意して下さい。 (オブジェクトが循環参照の一部の場合、任意のスレッドのガベージコレクションによって解放されてしまうかもしれません)。Python API 側からみれば、 tp_dealloc を呼び出すスレッドはグローバルインタプリタロック (GIL: Global Interpreter Lock) を獲得するので、これは問題ではありません。しかしながら、削除されようとしているオブジェクトが何らかの C や C++ ライブラリ由来のオブジェクトを削除する場合、 tp_dealloc を呼び出すスレッドのオブジェクトを削除することで、ライブラリの仮定している何らかの規約に違反しないように気を付ける必要があります。
数値オブジェクト構造体¶
-
PyNumberMethods
¶ この構造体は数値型プロトコルを実装するために使われる関数群へのポインタを保持しています。 以下のそれぞれの関数は 数値型プロトコル (number protocol) で解説されている似た名前の関数から利用されます。
以下は構造体の定義です:
typedef struct { binaryfunc nb_add; binaryfunc nb_subtract; binaryfunc nb_multiply; binaryfunc nb_remainder; binaryfunc nb_divmod; ternaryfunc nb_power; unaryfunc nb_negative; unaryfunc nb_positive; unaryfunc nb_absolute; inquiry nb_bool; unaryfunc nb_invert; binaryfunc nb_lshift; binaryfunc nb_rshift; binaryfunc nb_and; binaryfunc nb_xor; binaryfunc nb_or; unaryfunc nb_int; void *nb_reserved; unaryfunc nb_float; binaryfunc nb_inplace_add; binaryfunc nb_inplace_subtract; binaryfunc nb_inplace_multiply; binaryfunc nb_inplace_remainder; ternaryfunc nb_inplace_power; binaryfunc nb_inplace_lshift; binaryfunc nb_inplace_rshift; binaryfunc nb_inplace_and; binaryfunc nb_inplace_xor; binaryfunc nb_inplace_or; binaryfunc nb_floor_divide; binaryfunc nb_true_divide; binaryfunc nb_inplace_floor_divide; binaryfunc nb_inplace_true_divide; unaryfunc nb_index; binaryfunc nb_matrix_multiply; binaryfunc nb_inplace_matrix_multiply; } PyNumberMethods;
注釈
二項関数と三項関数は、すべてのオペランドの型をチェックしなければならず、必要な変換を実装しなければなりません (すくなくともオペランドの一つは定義している型のインスタンスです). もし与えられたオペランドに対して操作が定義されなければ、二項関数と三項関数は
Py_NotImplemented
を返さなければならず、他のエラーが起こった場合は、NULL
を返して例外を設定しなければなりません。注釈
nb_reserved
フィールドは常にNULL
でなければなりません。以前はnb_long
と呼ばれていて、 Python 3.0.1 で名前が変更されました。
マップオブジェクト構造体¶
-
PyMappingMethods
¶ この構造体はマップ型プロトコルを実装するために使われる関数群へのポインタを保持しています。 以下の3つのメンバを持っています:
-
lenfunc
PyMappingMethods.mp_length
¶ This function is used by
PyMapping_Length()
andPyObject_Size()
, and has the same signature. This slot may be set to NULL if the object has no defined length.
-
binaryfunc
PyMappingMethods.mp_subscript
¶ This function is used by
PyObject_GetItem()
and has the same signature. This slot must be filled for thePyMapping_Check()
function to return1
, it can be NULL otherwise.
-
objobjargproc
PyMappingMethods.mp_ass_subscript
¶ This function is used by
PyObject_SetItem()
andPyObject_DelItem()
. It has the same signature asPyObject_SetItem()
, but v can also be set to NULL to delete an item. If this slot is NULL, the object does not support item assignment and deletion.
シーケンスオブジェクト構造体¶
-
PySequenceMethods
¶ この構造体はシーケンス型プロトコルを実装するために使われる関数群へのポインタを保持しています。
-
lenfunc
PySequenceMethods.sq_length
¶ This function is used by
PySequence_Size()
andPyObject_Size()
, and has the same signature.
-
binaryfunc
PySequenceMethods.sq_concat
¶ This function is used by
PySequence_Concat()
and has the same signature. It is also used by the+
operator, after trying the numeric addition via thenb_add
slot.
-
ssizeargfunc
PySequenceMethods.sq_repeat
¶ This function is used by
PySequence_Repeat()
and has the same signature. It is also used by the*
operator, after trying numeric multiplication via thenb_multiply
slot.
-
ssizeargfunc
PySequenceMethods.sq_item
¶ This function is used by
PySequence_GetItem()
and has the same signature. This slot must be filled for thePySequence_Check()
function to return1
, it can be NULL otherwise.負のインデックスは次のように処理されます:
sq_length
スロットが埋められていれば、それを呼び出してシーケンスの長さから正のインデックスを計算し、sq_item
に渡します。sq_length
が NULL の場合は、インデックスはそのままこの関数に渡されます。
-
ssizeobjargproc
PySequenceMethods.sq_ass_item
¶ This function is used by
PySequence_SetItem()
and has the same signature. This slot may be left to NULL if the object does not support item assignment and deletion.
-
objobjproc
PySequenceMethods.sq_contains
¶ This function may be used by
PySequence_Contains()
and has the same signature. This slot may be left to NULL, in this casePySequence_Contains()
simply traverses the sequence until it finds a match.
-
binaryfunc
PySequenceMethods.sq_inplace_concat
¶ This function is used by
PySequence_InPlaceConcat()
and has the same signature. It should modify its first operand, and return it.
-
ssizeargfunc
PySequenceMethods.sq_inplace_repeat
¶ This function is used by
PySequence_InPlaceRepeat()
and has the same signature. It should modify its first operand, and return it.
バッファオブジェクト構造体 (buffer object structure)¶
-
PyBufferProcs
¶ この構造体は buffer プロトコル が要求する関数群へのポインタを保持しています。 そのプロトコルは、エクスポーターオブジェクトが如何にして、その内部データをコンシューマオブジェクトに渡すかを定義します。
-
getbufferproc
PyBufferProcs.bf_getbuffer
¶ この関数のシグネチャは以下の通りです:
int (PyObject *exporter, Py_buffer *view, int flags);
flags で指定された方法で view を埋めてほしいという exporter に対する要求を処理します。ステップ(3) を除いて、この関数の実装では以下のステップを行わなければなりません:
- リクエストが合致するか確認します。
合致しない場合は、
PyExc_BufferError
を送出し、view->obj
に NULL を設定し-1
を返します。 - 要求されたフィールドを埋めます。
- エクスポートした回数を保持する内部カウンタをインクリメントします。
view->obj
に exporter を設定し、view->obj
をインクリメントします。0
を返します。
exporter がバッファプロバイダのチェインかツリーの一部であれば、2つの主要な方式が使用できます:
- 再エクスポート: ツリーの各要素がエクスポートされるオブジェクトとして振る舞い、自身への新しい参照を
view->obj
へセットします。 - リダイレクト: バッファ要求がツリーのルートオブジェクトにリダイレクトされます。ここでは、
view->obj
はルートオブジェクトへの新しい参照になります。
view の個別のフィールドは バッファ構造体 の節で説明されており、エクスポートが特定の要求に対しどう対応しなければならないかの規則は、 バッファ要求のタイプ の節にあります。
Py_buffer
構造体の中から参照している全てのメモリはエクスポータに属し、コンシューマがいなくなるまで有効でなくてはなりません。format
、shape
、strides
、suboffsets
、internal
はコンシューマからは読み出し専用です。PyBuffer_FillInfo()
は、全てのリクエストタイプを正しく扱う際に、単純なバイトバッファを公開する簡単な方法を提供します。PyObject_GetBuffer()
は、この関数をラップするコンシューマ向けのインタフェースです。- リクエストが合致するか確認します。
合致しない場合は、
-
releasebufferproc
PyBufferProcs.bf_releasebuffer
¶ この関数のシグネチャは以下の通りです:
void (PyObject *exporter, Py_buffer *view);
バッファのリソースを開放する要求を処理します。もし開放する必要のあるリソースがない場合、
PyBufferProcs.bf_releasebuffer
は NULL にしても構いません。そうでない場合は、この関数の標準的な実装は、以下の任意の処理手順 (optional step) を行います:- エクスポートした回数を保持する内部カウンタをデクリメントします。
- カウンタが
0
の場合は、view に関連付けられた全てのメモリを解放します。
エクスポータは、バッファ固有のリソースを監視し続けるために
internal
フィールドを使わなければなりません。このフィールドは、コンシューマが view 引数としてオリジナルのバッファのコピーを渡しているであろう間、変わらないことが保証されています。この関数は、
view->obj
をデクリメントしてはいけません、なぜならそれはPyBuffer_Release()
で自動的に行われるからです(この方式は参照の循環を防ぐのに有用です)。PyBuffer_Release()
は、この関数をラップするコンシューマ向けのインタフェースです。
async オブジェクト構造体¶
バージョン 3.5 で追加.
-
PyAsyncMethods
¶ この構造体は awaitable オブジェクトと asynchronous iterator オブジェクトを実装するのに必要な関数へのポインタを保持しています。
以下は構造体の定義です:
typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; } PyAsyncMethods;
-
unaryfunc
PyAsyncMethods.am_await
¶ この関数のシグネチャは以下の通りです:
PyObject *am_await(PyObject *self)
返されるオブジェクトはイテレータでなければなりません。 つまりこのオブジェクトに対して
PyIter_Check()
が1
を返さなければなりません。オブジェクトが awaitable でない場合、このスロットを NULL に設定します。
-
unaryfunc
PyAsyncMethods.am_aiter
¶ この関数のシグネチャは以下の通りです:
PyObject *am_aiter(PyObject *self)
awaitable オブジェクトを返さなければなりません。 詳しいことは
__anext__()
を参照してください。オブジェクトが非同期反復処理のプロトコルを実装していない場合、このスロットを NULL に設定します。
-
unaryfunc
PyAsyncMethods.am_anext
¶ この関数のシグネチャは以下の通りです:
PyObject *am_anext(PyObject *self)
awaitable オブジェクトを返さなければなりません。 詳しいことは
__anext__()
を参照してください。 このスロットは NULL に設定されていることもあります。