この節ではさまざまな実装可能なタイプメソッドと、 それらが何をするものであるかについて、ざっと説明します。
以下は PyTypeObject の定義です。デバッグビルドでしか使われない いくつかのメンバは省いてあります:
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;
たくさんのメソッドがありますね。でもそんなに心配する必要はありません。 定義したい型があるなら、実装するのはこのうちのごくわずかですむことが ほとんどです。
すでに予想されているでしょうが、これらの多様なハンドラについて、
これからより詳しい情報を提供します。しかしこれらのメンバが構造体中で
定義されている順番は無視します。というのは、これらのメンバの現れる
順序は歴史的な遺産によるものだからです。型を初期化するさいに、これらの
メンバを正しい順序で並べるよう、くれぐれも注意してください。
ふつういちばん簡単なのは、必要なメンバがすべて含まれている
(たとえそれらが 0
に初期化されていても) 例をとってきて、
自分の型に合わせるよう変更をくわえることです。
char *tp_name; /* 表示用 */
これは型の名前です。前節で説明したように、これはいろいろな場面で 現れ、ほとんどは診断用の目的で使われるものです。 なので、そのような場面で役に立つであろう名前を選んでください。
int tp_basicsize, tp_itemsize; /* 割り当て用 */
これらのメンバは、この型のオブジェクトが作成されるときにどれだけのメモリを 割り当てればよいのかをランタイムに指示します。Python には可変長の構造体 (文字列やリストなどを想像してください) に対する組み込みのサポートが ある程度あり、ここで tp_itemsize メンバが使われます。 これらについてはあとでふれます。
char *tp_doc;
ここには Python スクリプトリファレンス obj.__doc__
が doc string を
返すときの文字列 (あるいはそのアドレス) を入れます。
では次に、ほとんどの拡張型が実装するであろう基本的な タイプメソッドに入っていきます。