型オブジェクト¶
新スタイルの型を定義する構造体: PyTypeObject 構造体は、おそらく Python オブジェクトシステムの中で最も重要な構造体の1つでしょう。型オブジェクトは PyObject_*() 系や PyType_*() 系の関数で扱えますが、ほとんどの Python アプリケーションにとって、さして面白みのある機能を提供しません。型オブジェクトはオブジェクトがどのように振舞うかを決める基盤ですから、インタプリタ自体や新たな型を定義する拡張モジュールでは非常に重要な存在です。
型オブジェクトは標準の型 (standard type) に比べるとかなり大きな構造体です。各型オブジェクトは多くの値を保持しており、そのほとんどは C 関数へのポインタで、それぞれの関数はその型の機能の小さい部分を実装しています。この節では、型オブジェクトの各フィールドについて詳細を説明します。各フィールドは、構造体内で出現する順番に説明されています。
Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, coercion, 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
char *tp_name; /* For printing, in format "<module>.<name>" */
int tp_basicsize, tp_itemsize; /* For allocation */
/* Methods to implement standard operations */
destructor tp_dealloc;
printfunc tp_print;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
cmpfunc tp_compare;
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 */
long tp_flags;
char *tp_doc; /* Documentation string */
/* Assigned meaning in release 2.0 */
/* call function for all accessible objects */
traverseproc tp_traverse;
/* delete references to contained objects */
inquiry tp_clear;
/* Assigned meaning in release 2.1 */
/* rich comparisons */
richcmpfunc tp_richcompare;
/* weak reference enabler */
long tp_weaklistoffset;
/* Added in release 2.2 */
/* 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;
long 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;
} 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が該当する型を指しているオブジェクト) は参照をカウントする対象には なりません 。動的にメモリ確保される型オブジェクトの場合、インスタンスは参照カウントの対象に なります 。サブタイプはこのフィールドを継承しません。
バージョン 2.5 で変更: このフィールドは以前は
intでした。この変更により、 64bit システムを正しくサポートするには修正が必要になります。
-
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 の場合には初期化します: Python 2.2 では、&PyType_Typeにセットします; in Python 2.2.1 およびそれ以降では基底クラスのob_typeフィールドに初期化します。ob_typeが非ゼロの場合、PyType_Ready()はこのフィールドを変更しません。Python 2.2 では、サブタイプはこのフィールドを継承しません。 2.2.1 と 2.3 以降では、サブタイプはこのフィールドを継承します。
-
Py_ssize_t
PyVarObject.ob_size¶ 静的にメモリ確保されている型オブジェクトの場合、このフィールドはゼロに初期化されます。動的にメモリ確保されている型オブジェクトの場合、このフィールドは内部使用される特殊な意味を持ちます。
サブタイプはこのフィールドを継承しません。
-
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と N かけるtp_itemsizeの加算になります。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 ヘッダサイズは入っていません (これは Python 2.2 からの新しい仕様です; 2.1 や 2.0 では、GC ヘッダサイズはtp_basicsizeに入っていました)。これらのフィールドはサブタイプに別々に継承されます。基底タイプが 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¶ オプションのフィールドで、インスタンスの出力 (print) を行う関数を指すポインタです。
出力関数は、インスタンスが 実体のある (real) ファイルに出力される場合にのみ呼び出されます; (
StringIOインスタンスのような) 擬似ファイルに出力される場合には、インスタンスのtp_reprやtp_strが指す関数が呼び出され、文字列への変換を行います。また、tp_printが NULL の場合にもこれらの関数が呼び出されます。tp_reprやtp_strと異なる出力を生成するようなtp_printは、決して型に実装してはなりません。出力関数は
PyObject_Print()と同じシグネチャ:int tp_print(PyObject *self, FILE *file, int flags)で呼び出されます。 self 引数は出力されるインスタンスを指します。 file 引数は出力先となる標準入出力 (stdio) ファイルです。 flags 引数はフラグビットを組み合わせた値です。現在定義されているフラグビットはPy_PRINT_RAWのみです。Py_PRINT_RAWフラグビットがセットされていれば、インスタンスはtp_strと同じ書式で出力されます;Py_PRINT_RAWフラグビットがクリアされていれば、インスタンスはtp_reprと同じ書式で出力されます。操作中にエラーが生じたときは、この関数は-1を返して例外状態をセットしなければなりません。tp_printフィールドは撤廃されるかもしれません。いずれにせよ、tp_printは定義せず、代わりにtp_reprやtp_strに頼って出力を行うようにしてください。サブタイプはこのフィールドを継承します。
-
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を両方とも継承します。
-
cmpfunc
PyTypeObject.tp_compare¶ オプションのフィールドです。ポインタで、三値比較 (three-way comparison) を行う関数を指します。
シグネチャは
PyObject_Compare()と同じです。この関数は self が other よりも大きければ1, self と other の値が等しければ0, self が other より小さければ-1を返します。この関数は、比較操作中にエラーが生じた場合、例外状態をセットして-1を返さねばなりません。このフィールドは
tp_richcompareおよびtp_hashと共にサブタイプに継承されます: すなわち、サブタイプのtp_compare,tp_richcompareおよびtp_hashが共に NULL の場合、サブタイプは基底タイプからtp_compare,tp_richcompare,tp_hashの三つを一緒に継承します。
-
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()と同じです。この関数は C のlong型の値を返さねばなりません。通常時には-1を戻り値にしてはなりません; ハッシュ値の計算中にエラーが生じた場合、関数は例外をセットして-1を返さねばなりません。このフィールドは明示的に
PyObject_HashNotImplemented()に設定することで、親 type からのハッシュメソッドの継承をブロックすることができます。これは Python レベルでの__hash__ = Noneと同等に解釈され、isinstance(o, collections.Hashable)が正しくFalseを返すようになります。逆もまた可能であることに注意してください - Python レベルで__hash__ = Noneを設定することでtp_hashスロットはPyObject_HashNotImplemented()に設定されます。このフィールドが設定されていない場合、二つの可能性があります:
tp_compareおよびtp_richcompareフィールドの両方が NULL の場合、オブジェクトのアドレスに基づいたデフォルトのハッシュ値が返されます; それ以外の場合、TypeErrorが送出されます。このフィールドは
tp_compareおよびtp_richcompareと共にサブタイプに継承されます: すなわち、サブタイプのtp_compare,tp_richcompareおよびtp_hashが共に NULL の場合、サブタイプは基底タイプからtp_compare,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フィールド自体は継承されませんが、これに含まれるフィールドは個別に継承されます。
-
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フラグビットがクリアで、かつ (Py_TPFLAGS_HAVE_RICHCOMPAREフラグビットの指定によって)tp_traverseおよびtp_clearフィールドがサブタイプ内に存在しており、かつ値が NULL の場合に基底タイプから値を継承します。以下に挙げるビットマスクは現在定義されているものです; フラグは
|演算子で論理和を取ってtp_flagsフィールドの値を作成できます。PyType_HasFeature()マクロは型とフラグ値、 tp および f をとり、tp->tp_flags & fが非ゼロかどうか調べます。-
Py_TPFLAGS_HAVE_GETCHARBUFFER¶ このビットがセットされていれば、
tp_as_bufferが参照するPyBufferProcs構造体にはbf_getcharbufferフィールドがあります。
-
Py_TPFLAGS_HAVE_SEQUENCE_IN¶ このビットがセットされていれば、
tp_as_sequenceが参照するPySequenceMethods構造体にはsq_containsフィールドがあります。
-
Py_TPFLAGS_GC¶ このビットは旧式のものです。このシンボルが指し示していたビットはもはや使われていません。シンボルの現在の定義はゼロになっています。
-
Py_TPFLAGS_HAVE_INPLACEOPS¶ このビットがセットされていれば、
tp_as_sequenceが参照するPySequenceMethods構造体、およびtp_as_numberが参照するPyNumberMethods構造体には in-place 演算に関するフィールドが入っています。具体的に言うと、PyNumberMethods構造体はフィールドnb_inplace_add,nb_inplace_subtract,nb_inplace_multiply,nb_inplace_divide,nb_inplace_remainder,nb_inplace_power,nb_inplace_lshift,nb_inplace_rshift,nb_inplace_and,nb_inplace_xor,およびnb_inplace_orを持つことになります; また、PySequenceMethods構造体はフィールドsq_inplace_concatおよびsq_inplace_repeatを持つことになります。
-
Py_TPFLAGS_CHECKTYPES¶ このビットがセットされていれば、
tp_as_numberが参照するPyNumberMethods構造体内で定義されている二項演算子および三項演算子は任意のオブジェクト型を非演算子にとるようになり、必要に応じて引数の型変換を行います。このビットがクリアなら、演算子は全ての引数が現在のオブジェクト型と同じであるよう要求し、演算の呼び出し側は演算に先立って型変換を行うものと想定します。対象となる演算子はnb_add,nb_subtract,nb_multiply,nb_divide,nb_remainder,nb_divmod,nb_power,nb_lshift,nb_rshift,nb_and,nb_xor,およびnb_orです。
-
Py_TPFLAGS_HAVE_RICHCOMPARE¶ このビットがセットされていれば、型オブジェクトには
tp_richcompareフィールド、そしてtp_traverseおよびtp_clearフィールドがあります。
-
Py_TPFLAGS_HAVE_WEAKREFS¶ このビットがセットされていれば、構造体には
tp_weaklistoffsetフィールドが定義されています。tp_weaklistoffsetフィールドの値がゼロより大きければ、この型のインスタンスは弱参照で参照できます。
-
Py_TPFLAGS_HAVE_ITER¶ このビットがセットされていれば、型オブジェクトには
tp_iterおよびtp_iternextフィールドがあります。
-
Py_TPFLAGS_HAVE_CLASS¶ このビットがセットされていれば、型オブジェクトは Python 2.2 以降で定義されている新たなフィールド:
tp_methods,tp_members,tp_getset,tp_base,tp_dict,tp_descr_get,tp_descr_set,tp_dictoffset,tp_init,tp_alloc,tp_new,tp_free,tp_is_gc,tp_bases,tp_mro,tp_cache,tp_subclasses,およびtp_weaklistがあります。
-
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_HAVE_GCがクリアでもPy_TPFLAGS_HAVE_RICHCOMPAREがセットされている場合には存在します。
-
Py_TPFLAGS_DEFAULT¶ 型オブジェクトおよび拡張機能構造体の特定のフィールドの存在の有無に関連する全てのビットからなるビットマスクです。現状では、このビットマスクには以下のビット:
Py_TPFLAGS_HAVE_GETCHARBUFFER,Py_TPFLAGS_HAVE_SEQUENCE_IN,Py_TPFLAGS_HAVE_INPLACEOPS,Py_TPFLAGS_HAVE_RICHCOMPARE,Py_TPFLAGS_HAVE_WEAKREFS,Py_TPFLAGS_HAVE_ITER,およびPy_TPFLAGS_HAVE_CLASSが入っています。
-
-
char*
PyTypeObject.tp_doc¶ オプションのフィールドです。ポインタで、この型オブジェクトの docstring を与える NUL 終端された C の文字列を指します。この値は型オブジェクトと型のインスタンスにおける
__doc__属性として公開されます。サブタイプはこのフィールドを継承 しません 。
以下の三つのフィールドは、 Py_TPFLAGS_HAVE_RICHCOMPARE フラグビットがセットされている場合にのみ存在します。
-
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の値がサブタイプで全てゼロになっており、 かつ サブタイプでPy_TPFLAGS_HAVE_RICHCOMPAREフラグビットがセットされている場合に、基底タイプから値を継承します。
-
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の値がサブタイプで全てゼロになっており、 かつ サブタイプでPy_TPFLAGS_HAVE_RICHCOMPAREフラグビットがセットされている場合に、基底タイプから値を継承します。
-
richcmpfunc
PyTypeObject.tp_richcompare¶ オプションのフィールドで、拡張比較関数 (rich comparison function) を指すポインタです。拡張比較関数のシグネチャは
PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)です。この関数は、比較結果を返すべきです。(普通は
Py_TrueかPy_Falseです。) 比較が未定義の場合は、Py_NotImplementedを、それ以外のエラーが発生した場合には例外状態をセットしてNULLを返さなければなりません。注釈
限られた種類の比較だけが可能 (例えば、
==と!=が可能で<などが不可能) な型を実装したい場合、拡張比較関数で直接TypeErrorを返します。このフィールドは
tp_compareおよびtp_hashと共にサブタイプに継承されます: すなわち、サブタイプのtp_compare,tp_richcompareおよびtp_hashが共に NULL の場合、サブタイプは基底タイプからtp_compare,tp_richcompare,tp_hashの三つを一緒に継承します。tp_richcompareおよびPyObject_RichCompare()関数の第三引数に使うための定数としては以下が定義されています:定数
比較
Py_LT<Py_LE<=Py_EQ==Py_NE!=Py_GT>Py_GE>=
次のフィールドは、 Py_TPFLAGS_HAVE_WEAKREFS フラグビットがセットされている場合にのみ存在します。
-
long
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を継承します。
次の二つのフィールドは、 Py_TPFLAGS_HAVE_ITER フラグビットがセットされている場合にのみ存在します。
-
getiterfunc
PyTypeObject.tp_iter¶ オプションの変数で、そのオブジェクトのイテレータを返す関数へのポインタです。この値が存在することは、通常この型のインスタンスがイテレート可能であることを示しています。(しかし、シーケンスはこの関数がなくてもイテレート可能ですし、旧スタイルクラスのインスタンスは
__iter__()メソッドを定義していなくてもこの関数を持っています)この関数は
PyObject_GetIter()と同じシグネチャを持っています。サブタイプはこのフィールドを継承します。
-
iternextfunc
PyTypeObject.tp_iternext¶ オプションのフィールドで、イテレータにおいて次の要素を返す関数へのポインタです。イテレータの要素がなくなると、この関数は NULL を返さなければなりません。
StopIteration例外は設定してもしなくても良いです。その他のエラーが発生したときも、 NULL を返さなければなりません。このフィールドがあると、通常この型のインスタンスがイテレータであることを示します (ただし、旧スタイルのインスタンスでは、たとえnext()メソッドが定義されていなくても常にこの関数を持っています)。イテレータ型では、
tp_iter関数も定義されていなければならず、その関数は (新たなイテレータインスタンスではなく) イテレータインスタンス自体を返さねばなりません。この関数のシグネチャは
PyIter_Next()と同じです。サブタイプはこのフィールドを継承します。
次の tp_weaklist までのフィールドは、 Py_TPFLAGS_HAVE_CLASS フラグビットがセットされている場合にのみ存在します。
-
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__()のような) オーバロード用演算でないときだけです。サブタイプはこのフィールドを継承しません (が、この辞書内で定義されている属性は異なるメカニズムで継承されます)。
-
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 を設定して値を消します。 このフィールドはサブタイプに継承されます。
-
long
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の符号を使うため、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_initが呼び出されます。tp_newが元の型のサブタイプでない別の型を返す場合、tp_initは全く呼び出されません;tp_newが元の型のサブタイプのインスタンスを返す場合、サブタイプのtp_initが呼び出されます。 (VERSION NOTE: ここに書かれている内容は、Python 2.2.1 以降での実装に関するものです。Python 2.2 では、tp_initは NULL でない限りtp_newが返す全てのオブジェクトに対して常に呼び出されます。) not NULL.)サブタイプはこのフィールドを継承します。
-
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になっている静的な型では継承しません。後者が例外になっているのは、旧式の拡張型が Python 2.2 でリンクされたときに呼び出し可能オブジェクトにならないようにするための予防措置です。
-
destructor
PyTypeObject.tp_free¶ オプションのフィールドです。ポインタで、インスタンスのメモリ解放関数を指します。
この関数のシグネチャは少し変更されています; Python 2.2 および 2.2.1 では、シグネチャは
destructorvoid tp_free(PyObject *)
でしたが、 Python 2.3 以降では、シグネチャは
freefuncになっています:void tp_free(void *)
両方のバージョンと互換性のある初期値は
_PyObject_Delです。_PyObject_Delの定義は Python 2.3 で適切に対応できるよう変更されました。静的なサブタイプはこのフィールドを継承しますが、動的なサブタイプ (
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は、型のメモリ確保が静的か動的かを区別するためにこの関数を定義しています。)サブタイプはこのフィールドを継承します。 (VERSION NOTE: Python 2.2 では、このフィールドは継承されませんでした。 2.2.1 以降のバージョンから継承されるようになりました。)
-
PyObject*
PyTypeObject.tp_bases¶ 基底型からなるタプルです。
class文で生成されたクラスの場合このフィールドがセットされます。静的に定義されている型の場合には、このフィールドは NULL になります。このフィールドは継承されません。
-
PyObject*
PyTypeObject.tp_mro¶ 基底タイプ群を展開した集合が入っているタプルです。集合は該当する型自体からはじまり、
objectで終わります。メソッド解決順序 (Method Resolution Order) に従って並んでいます。このフィールドは継承されません; フィールドの値は
PyType_Ready()で毎回計算されます。
The remaining fields are only defined if the feature test macro
COUNT_ALLOCS is defined, and are for internal use only. They are
documented here for completeness. None of these fields are inherited by
subtypes. See the PYTHONSHOWALLOCCOUNT environment variable.
-
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_divide; binaryfunc nb_remainder; binaryfunc nb_divmod; ternaryfunc nb_power; unaryfunc nb_negative; unaryfunc nb_positive; unaryfunc nb_absolute; inquiry nb_nonzero; /* Used by PyObject_IsTrue */ unaryfunc nb_invert; binaryfunc nb_lshift; binaryfunc nb_rshift; binaryfunc nb_and; binaryfunc nb_xor; binaryfunc nb_or; coercion nb_coerce; /* Used by the coerce() function */ unaryfunc nb_int; unaryfunc nb_long; unaryfunc nb_float; unaryfunc nb_oct; unaryfunc nb_hex; /* Added in release 2.0 */ binaryfunc nb_inplace_add; binaryfunc nb_inplace_subtract; binaryfunc nb_inplace_multiply; binaryfunc nb_inplace_divide; 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; /* Added in release 2.2 */ binaryfunc nb_floor_divide; binaryfunc nb_true_divide; binaryfunc nb_inplace_floor_divide; binaryfunc nb_inplace_true_divide; /* Added in release 2.5 */ unaryfunc nb_index; } PyNumberMethods;
2引数および3引数の関数は、 Py_TPFLAGS_CHECKTYPES フラグによっては、異なる種類の引数を受け取るかもしれません。
Py_TPFLAGS_CHECKTYPESがセットされていない場合、関数の引数はオブジェクトの型であることが保証されます。呼び出し側はnb_coerceメンバで指定されている型強制メソッドを呼び出して引数を変換する責任があります。-
coercion
PyNumberMethods.nb_coerce¶ この関数は
PyNumber_CoerceEx()から利用され、同じシグネチャを持ちます。最初の引数は定義された型のオブジェクトを指すポインタでなければなりません。共通の "大きな" 型への変換が可能であれば、この関数はポインタを変換後のオブジェクトへの新しい参照へ置き換えて、0を返します。変換ができないなら、この関数は1を返します。エラーが設定荒れた場合は、-1を返します。
-
coercion
Py_TPFLAGS_CHECKTYPESフラグがセットされている場合、2引数および 3引数関数はすべてのオペランドの型をチェクし、必要な変換を行わなければなりません。 (少なくとも、オペランドのうち1つは定義している型のものです) これは推奨された方式です。 Python 3 では型強制は完全に取り除かれています。
与えられたオペランドに対して操作が定義されていな場合は、2引数および3引数関数は Py_NotImplemented を返さなければなりません。その他のエラーが発生した場合は、例外を設定して NULL を返さなければなりません。
マップ型オブジェクト構造体¶
-
PyMappingMethods¶ 拡張型でマップ型プロトコルを実装するために使われる関数群へのポインタを保持するために使われる構造体です。以下の3つのメンバを持っています:
-
lenfunc
PyMappingMethods.mp_length¶ この関数は
PyMapping_Length()やPyObject_Size()から利用され、それらと同じシグネチャを持っています。オブジェクトが定義された長さを持たない場合は、このスロットは NULL に設定されることがあります。
-
binaryfunc
PyMappingMethods.mp_subscript¶ この関数は
PyObject_GetItem()から利用され、同じシグネチャを持っています。このスロットはPyMapping_Check()が1を返すためには必要で、そうでなければ NULL の場合があります。
-
objobjargproc
PyMappingMethods.mp_ass_subscript¶ この関数は
PyObject_SetItem()およびPyObject_DelItem()から利用されます。PyObject_SetItem()と同じシグネチャを持ちますが、 v に NULL を設定して要素の削除もできます。このスロットが NULL の場合は、このオブジェクトはアイテムの代入と削除をサポートしません。
シーケンスオブジェクト構造体¶
-
PySequenceMethods¶ 拡張型でシーケンス型プロトコルを実装するために使われる関数群へのポインタを保持するために使われる構造体です。
-
lenfunc
PySequenceMethods.sq_length¶ この関数は
PySequence_Size()やPyObject_Size()から利用され、それらと同じシグネチャを持っています。
-
binaryfunc
PySequenceMethods.sq_concat¶ この関数は
PySequence_Concat()で利用され、同じシグネチャを持っています。また、+演算子でも、nb_addスロットによる数値加算を試した後に利用されます。
-
ssizeargfunc
PySequenceMethods.sq_repeat¶ この関数は
PySequence_Repeat()で利用され、同じシグネチャを持っています。また、*演算でも、nb_multiplyスロットによる数値乗算を試したあとに利用されます。
-
ssizeargfunc
PySequenceMethods.sq_item¶ この関数は
PySequence_GetItem()から利用され、同じシグネチャを持っています。このスロットはPySequence_Check()が1を返すためには埋めなければならず、それ以外の場合は NULL の可能性があります。負のインデックスは次のように処理されます:
sq_lengthスロットが埋められていれば、それを呼び出してシーケンスの長さから正のインデックスを計算し、sq_itemに渡します。sq_lengthが NULL の場合は、インデックスはそのままこの関数に渡されます。
-
ssizeobjargproc
PySequenceMethods.sq_ass_item¶ この関数は
PySequence_SetItem()から利用され、同じシグネチャを持っています。 オブジェクトが要素の代入と削除をサポートしていない場合は、このスロットは NULL かもしれません。
-
objobjproc
PySequenceMethods.sq_contains¶ この関数は
PySequence_Contains()から利用され、同じシグネチャを持っています。このスロットは NULL の場合があり、その時PySequence_Contains()はシンプルにマッチするオブジェクトを見つけるまでシーケンスを巡回します。
-
binaryfunc
PySequenceMethods.sq_inplace_concat¶ この関数は
PySequence_InPlaceConcat()から利用され、同じシグネチャを持っています。この関数は最初のオペランドを修正してそれを返すべきです。
-
ssizeargfunc
PySequenceMethods.sq_inplace_repeat¶ この関数は
PySequence_InPlaceRepeat()から利用され、同じシグネチャを持っています。この関数は最初のオペランドを修正してそれを返すべきです。
バッファオブジェクト構造体 (buffer object structure)¶
バッファインタフェースは、あるオブジェクトの内部データを一連のデータチャンク (chunk) として見せるモデルを外部から利用できるようにします。各チャンクはポインタ/データ長からなるペアで指定します。チャンクはセグメント(segment) と呼ばれ、メモリ内に不連続的に配置されるものと想定されています。
バッファインタフェースを利用できるようにしたくないオブジェクトでは、 PyTypeObject 構造体の tp_as_buffer メンバを NULL にしなくてはなりません。利用できるようにする場合、 tp_as_buffer は PyBufferProcs 構造体を指さねばなりません。
注釈
PyTypeObject 構造体の tp_flags メンバの値を 0 でなく Py_TPFLAGS_DEFAULT にしておくことがとても重要です。この設定は、 PyBufferProcs 構造体に bf_getcharbuffer スロットが入っていることを Python ランタイムに教えます。 Python の古いバージョンには bf_getcharbuffer メンバが存在しないので、古い拡張モジュールを使おうとしている新しいバージョンの Python インタプリタは、このメンバがあるかどうかテストしてから使えるようにする必要があるのです。
-
PyBufferProcs¶ バッファプロトコルの実装を定義している関数群へのポインタを保持するのに使われる構造体です。
The first slot is
bf_getreadbuffer, of typereadbufferproc. If this slot is NULL, then the object does not support reading from the internal data. This is non-sensical, so implementors should fill this in, but callers should test that the slot contains a non-NULL value.The next slot is
bf_getwritebufferhaving typewritebufferproc. This slot may be NULL if the object does not allow writing into its returned buffers.The third slot is
bf_getsegcount, with typesegcountproc. This slot must not be NULL and is used to inform the caller how many segments the object contains. Simple objects such asPyString_TypeandPyBuffer_Typeobjects contain a single segment.The last slot is
bf_getcharbuffer, of typecharbufferproc. This slot will only be present if thePy_TPFLAGS_HAVE_GETCHARBUFFERflag is present in thetp_flagsfield of the object'sPyTypeObject. Before using this slot, the caller should test whether it is present by using thePyType_HasFeature()function. If the flag is present,bf_getcharbuffermay be NULL, indicating that the object's contents cannot be used as 8-bit characters. The slot function may also raise an error if the object's contents cannot be interpreted as 8-bit characters. For example, if the object is an array which is configured to hold floating point values, an exception may be raised if a caller attempts to usebf_getcharbufferto fetch a sequence of 8-bit characters. This notion of exporting the internal buffers as "text" is used to distinguish between objects that are binary in nature, and those which have character-based content.注釈
現在のポリシでは、文字 (character) はマルチバイト文字でもかまわないと決めているように思われます。従って、サイズ N のバッファが N 個のキャラクタからなるとはかぎらないことになります。
-
Py_TPFLAGS_HAVE_GETCHARBUFFER 型構造体中のフラグビットで、
bf_getcharbufferスロットが既知の値になっていることを示します。このフラグビットがセットされていたとしても、オブジェクトがバッファインタフェースをサポートしていることや、bf_getcharbufferスロットが NULL でないことを示すわけではありません。
-
Py_ssize_t
(*readbufferproc)(PyObject *self, Py_ssize_t segment, void **ptrptr)¶ *ptrptrの中の読み出し可能なバッファセグメントへのポインタを返します。この関数は例外を送出してもよく、送出する場合には-1を返さねばなりません。 segment に渡す値はゼロまたは正の値で、bf_getsegcountスロット関数が返すセグメント数よりも必ず小さな値でなければなりません。成功すると、セグメントのサイズを返し、*ptrptrをそのセグメントを指すポインタ値にセットします。
-
Py_ssize_t
(*writebufferproc)(PyObject *self, Py_ssize_t segment, void **ptrptr)¶ 読み出し可能なバッファセグメントへのポインタを
*ptrptrに返し、セグメントの長さを関数の戻り値として返します。エラーによる例外の場合には-1を-1を返さねばなりません。オブジェクトが呼び出し専用バッファしかサポートしていない場合にはTypeErrorを、 segment が存在しないセグメントを指している場合にはSystemErrorを送出しなければなりません。
