型オブジェクト¶
新スタイルの型を定義する構造体: 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 では、シグネチャは
destructor
void 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_getwritebuffer
having 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_Type
andPyBuffer_Type
objects contain a single segment.The last slot is
bf_getcharbuffer
, of typecharbufferproc
. This slot will only be present if thePy_TPFLAGS_HAVE_GETCHARBUFFER
flag is present in thetp_flags
field 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_getcharbuffer
may 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_getcharbuffer
to 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
を送出しなければなりません。