タイプオブジェクト
おそらく、Pythonオブジェクトシステムの最も重要な構造の1つは、新しい型を定義する構造、 PyTypeObject 構造です。 型オブジェクトは、 PyObject _ * または PyType _ * 関数のいずれかを使用して処理できますが、ほとんどのPythonアプリケーションにとって興味深いものはあまりありません。 これらのオブジェクトは、オブジェクトの動作の基本であるため、インタープリター自体および新しいタイプを実装する拡張モジュールにとって非常に重要です。
型オブジェクトは、ほとんどの標準型と比較してかなり大きいです。 サイズの理由は、各型オブジェクトが多数の値、主にC関数ポインターを格納し、それぞれが型の機能のごく一部を実装するためです。 このセクションでは、タイプオブジェクトのフィールドについて詳しく説明します。 フィールドは、構造内で発生する順序で説明されます。
以下のクイックリファレンスに加えて、の例セクションでは、 PyTypeObject の意味と使用法について一目でわかります。
クイックリファレンス
「tpスロット」
COUNT_ALLOCS
が定義されている場合、次の(内部のみの)フィールドも存在します。
- 1
括弧内のスロット名は、(事実上)非推奨であることを示します。 山括弧内の名前は読み取り専用として扱う必要があります。 角括弧内の名前は内部使用のみです。 「「 」(プレフィックスとして)は、フィールドが必須であることを意味します(非
NULL
)。- 2
列:
「O」:
PyBaseObject_Type
に設定“ T” : PyType_Type に設定
「D」:デフォルト(スロットが
NULL
に設定されている場合)X - PyType_Ready sets this value if it is NULL ~ - PyType_Ready always sets this value (it should be NULL) ? - PyType_Ready may set this value depending on other slots Also see the inheritance column ("I").
「私」:継承
X - type slot is inherited via PyType_Ready if defined with a NULL value % - the slots of the sub-struct are inherited individually G - inherited, but only in combination with other slots; see the slot's description ? - it's complicated; see the slot's description
一部のスロットは、通常の属性ルックアップチェーンを通じて効果的に継承されることに注意してください。
サブスロット
スロットtypedef
詳細については、以下の Slot Type typedefs を参照してください。
PyTypeObjectの定義
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;
Py_ssize_t tp_vectorcall_offset;
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;
PyObjectスロット
タイプオブジェクト構造は、 PyVarObject 構造を拡張します。 ob_size
フィールドは、動的型に使用されます(type_new()
によって作成され、通常はクラスステートメントから呼び出されます)。 PyType_Type (メタタイプ)は tp_itemsize を初期化することに注意してください。これは、そのインスタンス(つまり、 タイプオブジェクト) must にはob_size
フィールドが必要です。
- PyObject *PyObject._ob_next
PyObject *PyObject._ob_prev
これらのフィールドは、マクロ
Py_TRACE_REFS
が定義されている場合にのみ存在します。NULL
への初期化は、PyObject_HEAD_INIT
マクロによって処理されます。 静的に割り当てられたオブジェクトの場合、これらのフィールドは常にNULL
のままです。 動的に割り当てられたオブジェクトの場合、これら2つのフィールドは、ヒープ上のすべてのライブオブジェクトの二重リンクリストにオブジェクトをリンクするために使用されます。 これは、さまざまなデバッグ目的に使用できます。 現在のところ、唯一の用途は、環境変数 PYTHONDUMPREFS が設定されている場合に、実行の終了時にまだ生きているオブジェクトを印刷することです。継承:
これらのフィールドはサブタイプに継承されません。
- Py_ssize_t PyObject.ob_refcnt
これは、
PyObject_HEAD_INIT
マクロによって1
に初期化されたタイプオブジェクトの参照カウントです。 静的に割り当てられた型オブジェクトの場合、型のインスタンス(ob_type
が型を指すオブジェクト)はではなくは参照としてカウントされることに注意してください。 ただし、動的に割り当てられた型オブジェクトの場合、インスタンス do は参照としてカウントされます。継承:
このフィールドはサブタイプに継承されません。
- PyTypeObject *PyObject.ob_type
これはタイプのタイプ、つまりメタタイプです。
PyObject_HEAD_INIT
マクロへの引数によって初期化され、その値は通常&PyType_Type
である必要があります。 ただし、(少なくとも)Windowsで使用可能でなければならない動的にロード可能な拡張モジュールの場合、コンパイラーは、これが有効なイニシャライザーではないと文句を言います。 したがって、慣例では、NULL
をPyObject_HEAD_INIT
マクロに渡し、モジュールの初期化関数の開始時に、他の処理を行う前にこのフィールドを明示的に初期化します。 これは通常、次のように行われます。Foo_Type.ob_type = &PyType_Type;
これは、タイプのインスタンスを作成する前に実行する必要があります。 PyType_Ready()は、
ob_type
がNULL
であるかどうかを確認し、そうである場合は、基本クラスのob_type
フィールドに初期化します。 PyType_Ready()は、このフィールドがゼロ以外の場合、このフィールドを変更しません。継承:
このフィールドはサブタイプに継承されます。
PyVarObjectスロット
- Py_ssize_t PyVarObject.ob_size
静的に割り当てられた型オブジェクトの場合、これはゼロに初期化する必要があります。 動的に割り当てられたタイプオブジェクトの場合、このフィールドには特別な内部的な意味があります。
継承:
このフィールドはサブタイプに継承されません。
PyTypeObjectスロット
各スロットには、継承について説明するセクションがあります。 フィールドがNULL
に設定されているときに、 PyType_Ready()が値を設定する可能性がある場合は、「デフォルト」セクションもあります。 (PyBaseObject_Type
および PyType_Type に設定された多くのフィールドは、事実上デフォルトとして機能することに注意してください。)
- const char *PyTypeObject.tp_name
タイプの名前を含むNULで終了する文字列へのポインタ。 モジュールグローバルとしてアクセス可能な型の場合、文字列は完全なモジュール名、ドット、型名の順にする必要があります。 組み込み型の場合は、型名だけにする必要があります。 モジュールがパッケージのサブモジュールである場合、完全なパッケージ名は完全なモジュール名の一部です。 たとえば、パッケージ
P
のサブパッケージQ
のモジュールM
で定義されたT
という名前の型には、 tp_name イニシャライザー"P.Q.M.T"
。動的に割り当てられた型オブジェクトの場合、これは型名であり、型dictにキー
'__module__'
の値として明示的に格納されているモジュール名である必要があります。静的に割り当てられたタイプのオブジェクトの場合、tp_nameフィールドにはドットが含まれている必要があります。 最後のドットの前のすべてが
__module__
属性としてアクセス可能になり、最後のドットの後のすべてが __ name __ 属性としてアクセス可能になります。ドットが存在しない場合、 tp_name フィールド全体が __ name __ 属性としてアクセス可能になり、
__module__
属性は未定義です(辞書で明示的に設定されていない限り、上で説明した)。 これはあなたのタイプが酸洗いすることが不可能になることを意味します。 また、pydocで作成されたモジュールのドキュメントには記載されていません。このフィールドは
NULL
であってはなりません。 これは、 PyTypeObject()の唯一の必須フィールドです(潜在的に tp_itemsize を除く)。継承:
このフィールドはサブタイプに継承されません。
- Py_ssize_t PyTypeObject.tp_basicsize
Py_ssize_t PyTypeObject.tp_itemsize
これらのフィールドを使用すると、タイプのインスタンスのサイズをバイト単位で計算できます。
タイプには2種類あります。固定長のインスタンスを持つタイプにはゼロ tp_itemsize フィールドがあり、可変長のインスタンスを持つタイプにはゼロ以外の tp_itemsize フィールドがあります。 固定長のインスタンスを持つタイプの場合、 tp_basicsize で指定されているように、すべてのインスタンスのサイズは同じです。
可変長インスタンスを持つタイプの場合、インスタンスには
ob_size
フィールドが必要であり、インスタンスサイズは tp_basicsize に tp_itemsize のN倍を加えたものです。ここで、Nは「オブジェクトの長さ」。 Nの値は通常、インスタンスのob_size
フィールドに格納されます。 例外があります。たとえば、intは負のob_size
を使用して負の数を示し、Nはabs(ob_size)
です。 また、インスタンスレイアウトにob_size
フィールドが存在するからといって、インスタンス構造が可変長であることを意味するわけではありません(たとえば、リストタイプの構造には固定長のインスタンスがありますが、これらのインスタンスには意味のあるob_size
フィールド)。基本サイズには、マクロ PyObject_HEAD または PyObject_VAR_HEAD (インスタンス構造体の宣言に使用される方)によって宣言されたインスタンスのフィールドが含まれ、これには
_ob_prev
が含まれます。および_ob_next
フィールド(存在する場合)。 つまり、 tp_basicsize の初期化子を取得する唯一の正しい方法は、インスタンスレイアウトの宣言に使用される構造体でsizeof
演算子を使用することです。 基本サイズにはGCヘッダーサイズは含まれていません。配置に関する注意:変数アイテムに特定の配置が必要な場合は、 tp_basicsize の値で処理する必要があります。 例:型が
double
の配列を実装するとします。 tp_itemsize はsizeof(double)
です。 tp_basicsize がsizeof(double)
の倍数であるのはプログラマーの責任です(これがdouble
の配置要件であると想定)。可変長インスタンスを持つタイプの場合、このフィールドは
NULL
であってはなりません。継承:
これらのフィールドは、サブタイプによって個別に継承されます。 基本タイプにゼロ以外の tp_itemsize がある場合、サブタイプで tp_itemsize を別のゼロ以外の値に設定することは一般的に安全ではありません(ただし、これは基本タイプ)。
- destructor PyTypeObject.tp_dealloc
インスタンスデストラクタ関数へのポインタ。 この関数は、インスタンスが割り当て解除されないことが型によって保証されていない限り、定義する必要があります(シングルトン
None
およびEllipsis
の場合のように)。 関数のシグネチャは次のとおりです。void tp_dealloc(PyObject *self);
デストラクタ関数は、新しい参照カウントがゼロのときに Py_DECREF()および Py_XDECREF()マクロによって呼び出されます。 この時点で、インスタンスはまだ存在していますが、それへの参照はありません。 デストラクタ関数は、インスタンスが所有するすべての参照を解放し、インスタンスが所有するすべてのメモリバッファを解放し(バッファの割り当てに使用される割り当て関数に対応する解放関数を使用)、型の tp_free 関数を呼び出す必要があります。 タイプがサブタイプ化できない場合( Py_TPFLAGS_BASETYPE フラグビットが設定されていない場合)、 tp_free を介さずに、オブジェクトのデアロケーターを直接呼び出すことができます。 オブジェクトのデロケーターは、インスタンスの割り当てに使用されるものである必要があります。 これは通常、 PyObject_New()または
PyObject_VarNew()
を使用してインスタンスが割り当てられた場合は PyObject_Del()、インスタンスが割り当てられた場合は PyObject_GC_Del()です。 PyObject_GC_New()または PyObject_GC_NewVar()を使用します。最後に、型がヒープに割り当てられている場合( Py_TPFLAGS_HEAPTYPE )、deallocatorは、型deallocatorを呼び出した後、型オブジェクトの参照カウントをデクリメントする必要があります。 ダングリングポインタを回避するために、これを実現するための推奨される方法は次のとおりです。
static void foo_dealloc(foo_object *self) { PyTypeObject *tp = Py_TYPE(self); // free references and buffers here tp->tp_free(self); Py_DECREF(tp); }
継承:
このフィールドはサブタイプに継承されます。
- Py_ssize_t PyTypeObject.tp_vectorcall_offset
vectorcall プロトコルを使用してオブジェクトの呼び出しを実装する、インスタンスごとの関数へのオプションのオフセット。これは、より単純な tp_call のより効率的な代替手段です。
このフィールドは、フラグ _Py_TPFLAGS_HAVE_VECTORCALL が設定されている場合にのみ使用されます。 その場合、これは vectorcallfunc ポインターのインスタンスのオフセットを含む正の整数である必要があります。 署名は _PyObject_Vectorcall()の場合と同じです。
PyObject *vectorcallfunc(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
vectorcallfunc ポインターがゼロの場合、インスタンスは _Py_TPFLAGS_HAVE_VECTORCALL が設定されていないかのように動作します。インスタンスの呼び出しは tp_call にフォールバックします。
_Py_TPFLAGS_HAVE_VECTORCALL
を設定するクラスは、 tp_call も設定し、その動作が vectorcallfunc 関数と一致していることを確認する必要があります。 これは、 tp_call をPyVectorcall_Call
に設定することで実行できます。- PyObject *PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict)
callable の vectorcallfunc を、それぞれタプルとdictで指定された位置引数とキーワード引数を使用して呼び出します。
この機能は、
tp_call
スロットでの使用を目的としています。tp_call
にフォールバックせず、現在_Py_TPFLAGS_HAVE_VECTORCALL
フラグをチェックしていません。 オブジェクトを呼び出すには、代わりに PyObject_Call 関数の1つを使用してください。
ノート
ヒープタイプがvectorcallプロトコルを実装することはお勧めしません。 ユーザーがPythonコードで
__call__
を設定すると、tp_call
のみが更新され、vectorcall関数と矛盾する可能性があります。ノート
tp_vectorcall_offset
スロットのセマンティクスは暫定的なものであり、Python3.9で完成する予定です。 vectorcallを使用する場合は、Python3.9のコードを更新することを計画してください。バージョン3.8で変更:このスロットは、Python2.xでの印刷フォーマットに使用されていました。 Python 3.0から3.7では、予約され、
tp_print
という名前が付けられていました。継承:
このフィールドは、 tp_call とともにサブタイプに継承されます。サブタイプの tp_call が
NULL
の場合、サブタイプはベースタイプから tp_vectorcall_offset を継承します。ヒープタイプ(Pythonで定義されたサブクラスを含む)は _Py_TPFLAGS_HAVE_VECTORCALL フラグを継承しないことに注意してください。
- PyObject *PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict)
- getattrfunc PyTypeObject.tp_getattr
get-attribute-string関数へのオプションのポインター。
このフィールドは非推奨です。 定義するときは、 tp_getattro 関数と同じように機能する関数を指す必要がありますが、属性名を指定するためにPython文字列オブジェクトの代わりにC文字列を使用します。
継承:
グループ:
tp_getattr
、tp_getattro
このフィールドは、 tp_getattro とともにサブタイプに継承されます。サブタイプの tp_getattr および tp_getattro は両方とも
NULL
です。
- setattrfunc PyTypeObject.tp_setattr
属性を設定および削除するための関数へのオプションのポインタ。
このフィールドは非推奨です。 定義するときは、 tp_setattro 関数と同じように機能する関数を指す必要がありますが、属性名を指定するためにPython文字列オブジェクトの代わりにC文字列を使用します。
継承:
グループ:
tp_setattr
、tp_setattro
このフィールドは、 tp_setattro とともにサブタイプに継承されます。サブタイプの tp_setattr および tp_setattro は両方とも
NULL
です。
- PyAsyncMethods *PyTypeObject.tp_as_async
Cレベルで awaitable および asynchronous iterator プロトコルを実装するオブジェクトにのみ関連するフィールドを含む追加の構造体へのポインター。 詳細については、非同期オブジェクト構造を参照してください。
バージョン3.5の新機能:以前は
tp_compare
およびtp_reserved
と呼ばれていました。継承:
tp_as_async フィールドは継承されませんが、含まれているフィールドは個別に継承されます。
- reprfunc PyTypeObject.tp_repr
組み込み関数 repr()を実装する関数へのオプションのポインター。
署名は PyObject_Repr()の場合と同じです。
PyObject *tp_repr(PyObject *self);
関数は文字列またはUnicodeオブジェクトを返す必要があります。 理想的には、この関数は、 eval()に渡されたときに、適切な環境が与えられたときに同じ値のオブジェクトを返す文字列を返す必要があります。 これが不可能な場合は、
'<'
で始まり、'>'
で終わる文字列を返す必要があります。この文字列から、オブジェクトのタイプと値の両方を推測できます。継承:
このフィールドはサブタイプに継承されます。
ディフォルト:
このフィールドが設定されていない場合、
<%s object at %p>
の形式の文字列が返されます。ここで、%s
は型名に置き換えられ、%p
はオブジェクトのメモリアドレスに置き換えられます。
- PyNumberMethods *PyTypeObject.tp_as_number
番号プロトコルを実装するオブジェクトにのみ関連するフィールドを含む追加の構造体へのポインター。 これらのフィールドは、 Number Object Structures に記載されています。
継承:
tp_as_number フィールドは継承されませんが、含まれているフィールドは個別に継承されます。
- PySequenceMethods *PyTypeObject.tp_as_sequence
シーケンスプロトコルを実装するオブジェクトにのみ関連するフィールドを含む追加の構造体へのポインタ。 これらのフィールドは、シーケンスオブジェクト構造に記載されています。
継承:
tp_as_sequence フィールドは継承されませんが、含まれているフィールドは個別に継承されます。
- PyMappingMethods *PyTypeObject.tp_as_mapping
マッピングプロトコルを実装するオブジェクトにのみ関連するフィールドを含む追加の構造体へのポインタ。 これらのフィールドは、マッピングオブジェクト構造に記載されています。
継承:
tp_as_mapping フィールドは継承されませんが、含まれているフィールドは個別に継承されます。
- hashfunc PyTypeObject.tp_hash
組み込み関数 hash()を実装する関数へのオプションのポインター。
署名は PyObject_Hash()の場合と同じです。
Py_hash_t tp_hash(PyObject *);
値
-1
は通常の戻り値として返されるべきではありません。 ハッシュ値の計算中にエラーが発生した場合、関数は例外を設定して-1
を返す必要があります。このフィールドが設定されていない場合(および
tp_richcompare
が設定されていない場合)、オブジェクトのハッシュを取得しようとすると、 TypeError が発生します。 これは、 PyObject_HashNotImplemented()に設定するのと同じです。このフィールドを明示的に PyObject_HashNotImplemented()に設定して、親タイプからのハッシュメソッドの継承をブロックできます。 これは、Pythonレベルで
__hash__ = None
と同等であると解釈され、isinstance(o, collections.Hashable)
はFalse
を正しく返します。 逆もまた真であることに注意してください。Pythonレベルのクラスで__hash__ = None
を設定すると、tp_hash
スロットが PyObject_HashNotImplemented()に設定されます。継承:
グループ:
tp_hash
、tp_richcompare
このフィールドは、 tp_richcompare とともにサブタイプに継承されます。サブタイプの tp_richcompare との場合、サブタイプは tp_richcompare と tp_hash の両方を継承します。 ] tp_hash は両方とも
NULL
です。
- ternaryfunc PyTypeObject.tp_call
オブジェクトの呼び出しを実装する関数へのオプションのポインター。 オブジェクトが呼び出せない場合、これは
NULL
である必要があります。 署名は PyObject_Call()の場合と同じです。PyObject *tp_call(PyObject *self, PyObject *args, PyObject *kwargs);
継承:
このフィールドはサブタイプに継承されます。
- reprfunc PyTypeObject.tp_str
組み込み操作 str()を実装する関数へのオプションのポインター。 ( str は現在型であり、 str()はその型のコンストラクターを呼び出すことに注意してください。 このコンストラクターは PyObject_Str()を呼び出して実際の作業を行い、 PyObject_Str()はこのハンドラーを呼び出します。)
署名は PyObject_Str()の場合と同じです。
PyObject *tp_str(PyObject *self);
関数は文字列またはUnicodeオブジェクトを返す必要があります。 これは、特に print()関数によって使用される表現であるため、オブジェクトの「わかりやすい」文字列表現である必要があります。
継承:
このフィールドはサブタイプに継承されます。
ディフォルト:
このフィールドが設定されていない場合、 PyObject_Repr()が呼び出され、文字列表現が返されます。
- getattrofunc PyTypeObject.tp_getattro
get-attribute関数へのオプションのポインター。
署名は PyObject_GetAttr()の場合と同じです。
PyObject *tp_getattro(PyObject *self, PyObject *attr);
通常、このフィールドを PyObject_GenericGetAttr()に設定すると便利です。これは、オブジェクト属性を検索する通常の方法を実装します。
継承:
グループ:
tp_getattr
、tp_getattro
このフィールドは、 tp_getattr とともにサブタイプに継承されます。サブタイプの tp_getattr および tp_getattro は両方とも
NULL
です。ディフォルト:
PyBaseObject_Type
は PyObject_GenericGetAttr()を使用します。
- setattrofunc PyTypeObject.tp_setattro
属性を設定および削除するための関数へのオプションのポインタ。
署名は PyObject_SetAttr()の場合と同じです。
PyObject *tp_setattro(PyObject *self, PyObject *attr, PyObject *value);
また、属性を削除する場合は、 value を
NULL
に設定する必要があります。 通常、このフィールドを PyObject_GenericSetAttr()に設定すると便利です。これは、オブジェクト属性を設定する通常の方法を実装します。継承:
グループ:
tp_setattr
、tp_setattro
このフィールドは、 tp_setattr とともにサブタイプに継承されます。サブタイプの tp_setattr および tp_setattro は両方とも
NULL
です。ディフォルト:
PyBaseObject_Type
は PyObject_GenericSetAttr()を使用します。
- PyBufferProcs *PyTypeObject.tp_as_buffer
バッファインターフェイスを実装するオブジェクトにのみ関連するフィールドを含む追加の構造体へのポインタ。 これらのフィールドは、バッファオブジェクト構造に記載されています。
継承:
tp_as_buffer フィールドは継承されませんが、含まれているフィールドは個別に継承されます。
- unsigned long PyTypeObject.tp_flags
このフィールドは、さまざまなフラグのビットマスクです。 一部のフラグは、特定の状況でのバリアントセマンティクスを示します。 その他は、型オブジェクト(または tp_as_number 、 tp_as_sequence 、 tp_as_mapping 、および tp_as_buffer [ X268X])歴史的に常に存在するとは限らなかったものが有効です。 そのようなフラグビットがクリアされている場合、それが保護するタイプフィールドにアクセスしてはならず、代わりにゼロまたは
NULL
値を持っていると見なす必要があります。継承:
このフィールドの継承は複雑です。 ほとんどのフラグビットは個別に継承されます。 基本タイプにフラグビットが設定されている場合、サブタイプはこのフラグビットを継承します。 拡張構造が継承される場合、拡張構造に関連するフラグビットは厳密に継承されます。 フラグビットの基本型の値は、拡張構造へのポインタとともにサブタイプにコピーされます。 Py_TPFLAGS_HAVE_GC フラグビットは、 tp_traverse および tp_clear フィールドと一緒に継承されます。 Py_TPFLAGS_HAVE_GC フラグビットがサブタイプでクリアされ、サブタイプの tp_traverse および tp_clear フィールドが存在し、
NULL
値を持つ場合。ディフォルト:
PyBaseObject_Type
はPy_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
を使用します。ビットマスク:
現在、次のビットマスクが定義されています。 これらは、
|
演算子を使用してOR演算し、 tp_flags フィールドの値を形成できます。 マクロ PyType_HasFeature()は、型とフラグの値 tp と f を受け取り、tp->tp_flags & f
がゼロ以外かどうかをチェックします。- Py_TPFLAGS_HEAPTYPE
このビットは、タイプオブジェクト自体がヒープに割り当てられるときに設定されます。たとえば、 PyType_FromSpec()を使用して動的に作成されたタイプです。 この場合、そのインスタンスの
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
このビットは、オブジェクトがガベージコレクションをサポートしている場合に設定されます。 このビットが設定されている場合、インスタンスは PyObject_GC_New()を使用して作成し、 PyObject_GC_Del()を使用して破棄する必要があります。 詳細については、セクションサイクリックガベージコレクションのサポートを参照してください。 このビットは、GC関連のフィールド tp_traverse および tp_clear が型オブジェクトに存在することも意味します。
継承:
グループ: Py_TPFLAGS_HAVE_GC 、
tp_traverse
、tp_clear
Py_TPFLAGS_HAVE_GC フラグビットは、
tp_traverse
およびtp_clear
フィールドと一緒に継承されます。 Py_TPFLAGS_HAVE_GC フラグビットがサブタイプでクリアされていて、サブタイプのtp_traverse
およびtp_clear
フィールドが存在し、NULL
値を持っている場合。
- Py_TPFLAGS_DEFAULT
これは、型オブジェクトとその拡張構造内の特定のフィールドの存在に関連するすべてのビットのビットマスクです。 現在、次のビットが含まれています:
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION
、Py_TPFLAGS_HAVE_VERSION_TAG
。継承:
???
- Py_TPFLAGS_METHOD_DESCRIPTOR
このビットは、オブジェクトがバインドされていないメソッドのように動作することを示します。
このフラグが
type(meth)
に設定されている場合、次のようになります。meth.__get__(obj, cls)(*args, **kwds)
(obj
はNoneではありません)は、meth(obj, *args, **kwds)
と同等である必要があります。meth.__get__(None, cls)(*args, **kwds)
はmeth(*args, **kwds)
と同等である必要があります。
このフラグにより、
obj.meth()
などの一般的なメソッド呼び出しの最適化が可能になります。obj.meth
の一時的な「バインドされたメソッド」オブジェクトの作成が回避されます。バージョン3.8の新機能。
継承:
このフラグは、ヒープタイプに継承されることはありません。 拡張タイプの場合、 tp_descr_get が継承されるたびに継承されます。
- 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の新機能。
バージョン3.8以降非推奨:インタプリタは tp_finalize スロットが常に型構造に存在すると想定しているため、このフラグは不要になりました。
- _Py_TPFLAGS_HAVE_VECTORCALL
このビットは、クラスがvectorcallプロトコルを実装するときに設定されます。 詳細については、 tp_vectorcall_offset を参照してください。
継承:
このビットは、
tp_flags
がオーバーライドされない場合、 static サブタイプに設定されます。サブタイプの tp_call がNULL
およびサブタイプのPy_TPFLAGS_HEAPTYPE
が設定されていません。ヒープタイプは
_Py_TPFLAGS_HAVE_VECTORCALL
を継承しません。ノート
このフラグは暫定的なものであり、Python 3.9で公開される予定であり、名前が異なり、セマンティクスが変更されている可能性があります。 vectorcallを使用する場合は、Python3.9のコードを更新することを計画してください。
バージョン3.8の新機能。
- const char *PyTypeObject.tp_doc
この型オブジェクトのdocstringを与えるNULで終了するC文字列へのオプションのポインタ。 これは、タイプおよびタイプのインスタンスの
__doc__
属性として公開されます。継承:
このフィールドは、サブタイプによって継承されたではありません。
- traverseproc PyTypeObject.tp_traverse
ガベージコレクターのトラバーサル関数へのオプションのポインター。 これは、 Py_TPFLAGS_HAVE_GC フラグビットが設定されている場合にのみ使用されます。 署名は次のとおりです。
int tp_traverse(PyObject *self, visitproc visit, void *arg);
Pythonのガベージコレクションスキームの詳細については、セクション Cyclic GarbageCollectionのサポートを参照してください。
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()とにかくそのメンバーにアクセスすることをお勧めします。関数にはそれが含まれます。
警告
tp_traverse を実装する場合、インスタンスが所有する(それらへの強い参照を持つ)メンバーのみにアクセスする必要があります。 たとえば、オブジェクトが tp_weaklist スロットを介した弱参照をサポートしている場合、リンクリストをサポートするポインター( tp_weaklist が指すもの)は、ではなくにアクセスする必要があります。インスタンスはそれ自体への弱参照を直接所有していません(弱参照リストは弱参照機構をサポートするためにありますが、インスタンスがまだ生きている場合でも削除できるため、インスタンスにはその中の要素への強参照がありません)。
Py_VISIT()では、
local_traverse()
の visit および arg パラメーターにこれらの特定の名前を付ける必要があることに注意してください。 それらに何も名前を付けないでください。継承:
グループ: Py_TPFLAGS_HAVE_GC 、
tp_traverse
、tp_clear
このフィールドは、 tp_clear および Py_TPFLAGS_HAVE_GC フラグビットとともにサブタイプによって継承されます。フラグビット、 tp_traverse 、および tp_clear はすべて継承されます。サブタイプですべてゼロの場合は、基本タイプから。
- inquiry PyTypeObject.tp_clear
ガベージコレクターのclear関数へのオプションのポインター。 これは、 Py_TPFLAGS_HAVE_GC フラグビットが設定されている場合にのみ使用されます。 署名は次のとおりです。
int tp_clear(PyObject *);
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コードの呼び出しを含む一連の再生アクティビティがトリガーされる可能性があるためです(含まれているオブジェクトに関連付けられているファイナライザーまたはweakrefコールバックが原因)。 そのようなコードが self を再度参照できる場合は、その時点で含まれているオブジェクトへのポインタがNULL
であり、 self が含まれているオブジェクトを認識できるようにすることが重要です。使用できなくなりました。 Py_CLEAR()マクロは、安全な順序で操作を実行します。tp_clear 関数の目的は参照サイクルを中断することであるため、参照サイクルに参加できないPython文字列やPython整数などの含まれているオブジェクトをクリアする必要はありません。 一方、含まれているすべてのPythonオブジェクトをクリアし、タイプの tp_dealloc 関数を記述して tp_clear を呼び出すと便利な場合があります。
Pythonのガベージコレクションスキームの詳細については、セクション Cyclic GarbageCollectionのサポートを参照してください。
継承:
グループ: Py_TPFLAGS_HAVE_GC 、
tp_traverse
、tp_clear
このフィールドは、 tp_traverse および Py_TPFLAGS_HAVE_GC フラグビットとともにサブタイプによって継承されます。フラグビット、 tp_traverse 、および tp_clear はすべて継承されます。サブタイプですべてゼロの場合は、基本タイプから。
- richcmpfunc PyTypeObject.tp_richcompare
豊富な比較関数へのオプションのポインター。そのシグネチャは次のとおりです。
PyObject *tp_richcompare(PyObject *self, PyObject *other, int op);
最初のパラメーターは、 PyTypeObject で定義されている型のインスタンスであることが保証されています。
関数は比較の結果を返す必要があります(通常は
Py_True
またはPy_False
)。 比較が未定義の場合はPy_NotImplemented
を返す必要があり、別のエラーが発生した場合はNULL
を返し、例外条件を設定する必要があります。次の定数は、 tp_richcompare および PyObject_RichCompare()の3番目の引数として使用されるように定義されています。
絶え間ない
比較
Py_LT
<
Py_LE
<=
Py_EQ
==
Py_NE
!=
Py_GT
>
Py_GE
>=
次のマクロは、豊富な比較関数の記述を容易にするために定義されています。
- Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, op)
比較の結果に応じて、関数から
Py_True
またはPy_False
を返します。 VAL_AとVAL_Bは、C比較演算子で順序付け可能である必要があります(たとえば、C intまたはfloatの場合があります)。 3番目の引数は、 PyObject_RichCompare()のように、要求された操作を指定します。戻り値の参照カウントは適切にインクリメントされます。
エラーの場合、例外を設定し、関数から
NULL
を返します。バージョン3.7の新機能。
継承:
グループ:
tp_hash
、tp_richcompare
このフィールドは、 tp_hash とともにサブタイプに継承されます。サブタイプの tp_richcompare および tp_hash [の場合、サブタイプは tp_richcompare および tp_hash を継承します。 X190X]は両方とも
NULL
です。ディフォルト:
PyBaseObject_Type
は、tp_richcompare
の実装を提供します。これは、継承される場合があります。 ただし、tp_hash
のみが定義されている場合、継承された関数も使用されず、そのタイプのインスタンスは比較に参加できません。- Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, op)
- Py_ssize_t PyTypeObject.tp_weaklistoffset
このタイプのインスタンスが弱参照可能である場合、このフィールドはゼロより大きく、弱参照リストヘッドのインスタンス構造にオフセットが含まれます(GCヘッダーが存在する場合は無視されます)。 このオフセットは、
PyObject_ClearWeakRefs()
および PyWeakref _ * 関数によって使用されます。 インスタンス構造には、NULL
に初期化される PyObject * タイプのフィールドを含める必要があります。このフィールドを tp_weaklist と混同しないでください。 これは、型オブジェクト自体への弱参照のリストヘッドです。
継承:
このフィールドはサブタイプに継承されますが、以下のルールを参照してください。 サブタイプはこのオフセットをオーバーライドできます。 これは、サブタイプが基本タイプとは異なる弱参照リストヘッドを使用することを意味します。 リストヘッドは常に tp_weaklistoffset を介して検出されるため、これは問題にはなりません。
クラスステートメントで定義された型に __ slots __ 宣言がなく、その基本型のいずれも弱参照可能でない場合、インスタンスレイアウトに弱参照リストのヘッドスロットを追加し、そのスロットのオフセットの tp_weaklistoffset 。
タイプの
__slots__
宣言に__weakref__
という名前のスロットが含まれている場合、そのスロットはタイプのインスタンスの弱参照リストヘッドになり、スロットのオフセットはタイプの tp_weaklistoffset に格納されます。 ]。型の
__slots__
宣言に__weakref__
という名前のスロットが含まれていない場合、型はその tp_weaklistoffset を基本型から継承します。
- getiterfunc PyTypeObject.tp_iter
オブジェクトのイテレータを返す関数へのオプションのポインタ。 その存在は通常、このタイプのインスタンスが反復可能であることを示します(ただし、シーケンスはこの関数なしで反復可能である可能性があります)。
この関数には、 PyObject_GetIter()と同じ署名があります。
PyObject *tp_iter(PyObject *self);
継承:
このフィールドはサブタイプに継承されます。
- iternextfunc PyTypeObject.tp_iternext
イテレータ内の次の項目を返す関数へのオプションのポインタ。 署名は次のとおりです。
PyObject *tp_iternext(PyObject *self);
イテレータが使い果たされると、
NULL
を返す必要があります。 StopIteration 例外が設定される場合と設定されない場合があります。 別のエラーが発生した場合は、NULL
も返す必要があります。 その存在は、このタイプのインスタンスがイテレータであることを示します。イテレータ型は tp_iter 関数も定義する必要があり、その関数は(新しいイテレータインスタンスではなく)イテレータインスタンス自体を返す必要があります。
この関数には、 PyIter_Next()と同じ署名があります。
継承:
このフィールドはサブタイプに継承されます。
- struct PyMethodDef *PyTypeObject.tp_methods
このタイプの通常のメソッドを宣言する、 PyMethodDef 構造体の静的
NULL
で終了する配列へのオプションのポインター。配列内のエントリごとに、メソッド記述子を含むエントリがタイプのディクショナリに追加されます(以下の tp_dict を参照)。
継承:
このフィールドはサブタイプに継承されません(メソッドは別のメカニズムを介して継承されます)。
- struct PyMemberDef *PyTypeObject.tp_members
このタイプのインスタンスの通常のデータメンバー(フィールドまたはスロット)を宣言する、 PyMemberDef 構造の静的
NULL
で終了する配列へのオプションのポインター。配列内のエントリごとに、メンバー記述子を含むエントリがタイプのディクショナリに追加されます(以下の tp_dict を参照)。
継承:
このフィールドはサブタイプに継承されません(メンバーは別のメカニズムを介して継承されます)。
- struct PyGetSetDef *PyTypeObject.tp_getset
このタイプのインスタンスの計算された属性を宣言する、 PyGetSetDef 構造の静的
NULL
で終了する配列へのオプションのポインター。配列内のエントリごとに、getset記述子を含むエントリがタイプのディクショナリに追加されます(以下の tp_dict を参照)。
継承:
このフィールドはサブタイプに継承されません(計算された属性は別のメカニズムを介して継承されます)。
- PyTypeObject *PyTypeObject.tp_base
タイププロパティが継承される基本タイプへのオプションのポインタ。 このレベルでは、単一の継承のみがサポートされます。 多重継承では、メタタイプを呼び出して型オブジェクトを動的に作成する必要があります。
ノート
スロットの初期化には、グローバルを初期化する規則が適用されます。 C99では、初期化子が「アドレス定数」である必要があります。 PyType_GenericNew()のような関数指定子は、ポインターに暗黙的に変換され、有効なC99アドレス定数です。
ただし、単項 '&'演算子は、次のような非静的変数に適用されます。
PyBaseObject_Type()
アドレス定数を生成する必要はありません。 コンパイラはこれをサポートする場合がありますが(gccはサポートします)、MSVCはサポートしません。 両方のコンパイラは、この特定の動作において厳密に標準に準拠しています。したがって、 tp_base は拡張モジュールのinit関数で設定する必要があります。
継承:
このフィールドはサブタイプに継承されません(明らかに)。
ディフォルト:
このフィールドのデフォルトは
&PyBaseObject_Type
です(Pythonプログラマーにとってはタイプオブジェクトとして知られています)。
- PyObject *PyTypeObject.tp_dict
タイプの辞書は、 PyType_Ready()によってここに保存されます。
このフィールドは通常、PyType_Readyが呼び出される前に
NULL
に初期化する必要があります。 タイプの初期属性を含むディクショナリに初期化することもできます。 PyType_Ready()が型を初期化すると、オーバーロードされた操作(__add__()
など)に対応しない場合にのみ、型の追加属性をこのディクショナリに追加できます。継承:
このフィールドはサブタイプに継承されません(ただし、ここで定義されている属性は別のメカニズムを介して継承されます)。
ディフォルト:
このフィールドが
NULL
の場合、 PyType_Ready()は新しい辞書を割り当てます。警告
PyDict_SetItem()を使用したり、辞書C-APIを使用して tp_dict を変更したりすることは安全ではありません。
- 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 と混同しないでください。 これは、タイプオブジェクト自体の属性の辞書です。
このフィールドの値がゼロより大きい場合は、インスタンス構造の先頭からのオフセットを指定します。 値がゼロ未満の場合は、インスタンス構造の end からのオフセットを指定します。 負のオフセットは使用するのに費用がかかるため、インスタンス構造に可変長の部分が含まれている場合にのみ使用する必要があります。 これは、たとえば、 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
はインスタンスから取得されます。 intはob_size
の符号を使用して数値の符号を格納するため、絶対値が使用されます。 (この計算を自分で行う必要はありません。_PyObject_GetDictPtr()
によって行われます。)継承:
このフィールドはサブタイプに継承されますが、以下のルールを参照してください。 サブタイプはこのオフセットをオーバーライドできます。 これは、サブタイプインスタンスが基本タイプとは異なるオフセットでディクショナリを格納することを意味します。 辞書は常に tp_dictoffset を介して検出されるため、これは問題にはなりません。
クラスステートメントで定義された型に __ slots __ 宣言がなく、その基本型のいずれにもインスタンス変数ディクショナリがない場合、ディクショナリスロットがインスタンスレイアウトに追加され、 tp_dictoffset はそのスロットのオフセットに設定します。
クラスステートメントで定義された型に
__slots__
宣言がある場合、その型はその tp_dictoffset を基本型から継承します。( __ dict __ という名前のスロットを
__slots__
宣言に追加しても、期待される効果は得られず、混乱を招くだけです。 たぶん、これは__weakref__
のような機能として追加する必要があります。)ディフォルト:
このスロットにはデフォルトがありません。 静的型の場合、フィールドが
NULL
の場合、インスタンスに対して__dict__
は作成されません。
- 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 が呼び出されます。成功した場合は
0
を返し、エラーの場合は-1
を返し、例外を設定します。継承:
このフィールドはサブタイプに継承されます。
ディフォルト:
静的タイプの場合、このフィールドにはデフォルトがありません。
- allocfunc PyTypeObject.tp_alloc
インスタンス割り当て関数へのオプションのポインタ。
関数のシグネチャは次のとおりです。
PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems);
継承:
このフィールドは静的サブタイプに継承されますが、動的サブタイプ(クラスステートメントによって作成されたサブタイプ)には継承されません。
ディフォルト:
動的サブタイプの場合、このフィールドは常に PyType_GenericAlloc()に設定され、標準のヒープ割り当て戦略を強制します。
静的サブタイプの場合、
PyBaseObject_Type
は PyType_GenericAlloc()を使用します。 これは、静的に定義されたすべての型の推奨値です。
- newfunc PyTypeObject.tp_new
インスタンス作成関数へのオプションのポインター。
関数のシグネチャは次のとおりです。
PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds);
サブタイプ引数は、作成されるオブジェクトのタイプです。 args および kwds 引数は、型の呼び出しの位置引数とキーワード引数を表します。 サブタイプは、 tp_new 関数が呼び出されるタイプと同じである必要はないことに注意してください。 そのタイプのサブタイプである可能性があります(ただし、無関係のタイプではありません)。
tp_new 関数は、
subtype->tp_alloc(subtype, nitems)
を呼び出してオブジェクトにスペースを割り当て、絶対に必要なだけの初期化を実行する必要があります。 安全に無視または繰り返すことができる初期化は、 tp_init ハンドラーに配置する必要があります。 経験則として、不変型の場合、すべての初期化は tp_new で行う必要がありますが、可変型の場合、ほとんどの初期化は tp_init に延期する必要があります。継承:
このフィールドは、 tp_base が
NULL
または&PyBaseObject_Type
である静的型によって継承されないことを除いて、サブタイプによって継承されます。ディフォルト:
静的タイプの場合、このフィールドにはデフォルトがありません。 これは、スロットが
NULL
として定義されている場合、新しいインスタンスを作成するために型を呼び出すことができないことを意味します。 おそらく、ファクトリ関数のように、インスタンスを作成する他の方法があります。
- freefunc PyTypeObject.tp_free
インスタンスの割り当て解除関数へのオプションのポインター。 その署名は次のとおりです。
void tp_free(void *self);
この署名と互換性のあるイニシャライザーは PyObject_Free()です。
継承:
このフィールドは静的サブタイプに継承されますが、動的サブタイプ(クラスステートメントによって作成されたサブタイプ)には継承されません。
ディフォルト:
動的サブタイプでは、このフィールドは PyType_GenericAlloc()と Py_TPFLAGS_HAVE_GC フラグビットの値に一致するのに適したデアロケーターに設定されます。
静的サブタイプの場合、
PyBaseObject_Type
はPyObject_Delを使用します。
- inquiry PyTypeObject.tp_is_gc
ガベージコレクターによって呼び出される関数へのオプションのポインター。
ガベージコレクターは、特定のオブジェクトが収集可能かどうかを知る必要があります。 通常は、オブジェクトのタイプの tp_flags フィールドを確認し、 Py_TPFLAGS_HAVE_GC フラグビットを確認するだけで十分です。 ただし、一部のタイプには静的に割り当てられたインスタンスと動的に割り当てられたインスタンスが混在しており、静的に割り当てられたインスタンスは収集できません。 このようなタイプは、この関数を定義する必要があります。 収集可能なインスタンスの場合は
1
を返し、収集不可能なインスタンスの場合は0
を返す必要があります。 署名は次のとおりです。int tp_is_gc(PyObject *self);
(これの唯一の例はタイプ自体です。 メタタイプ PyType_Type は、静的に割り当てられたタイプと動的に割り当てられたタイプを区別するためにこの関数を定義します。)
継承:
このフィールドはサブタイプに継承されます。
ディフォルト:
このスロットにはデフォルトがありません。 このフィールドが
NULL
の場合、 Py_TPFLAGS_HAVE_GC が同等の機能として使用されます。
- PyObject *PyTypeObject.tp_bases
基本タイプのタプル。
これは、クラスステートメントによって作成された型に設定されます。 静的に定義された型の場合は
NULL
である必要があります。継承:
このフィールドは継承されません。
- PyObject *PyTypeObject.tp_mro
メソッド解決順序で、タイプ自体で始まり、 object で終わる拡張された基本タイプのセットを含むタプル。
継承:
このフィールドは継承されません。 PyType_Ready()によって新たに計算されます。
- PyObject *PyTypeObject.tp_cache
未使用。 内部でのみ使用。
継承:
このフィールドは継承されません。
- PyObject *PyTypeObject.tp_subclasses
サブクラスへの弱参照のリスト。 内部でのみ使用。
継承:
このフィールドは継承されません。
- PyObject *PyTypeObject.tp_weaklist
この型オブジェクトへの弱参照の弱参照リストヘッド。 継承されません。 内部でのみ使用。
継承:
このフィールドは継承されません。
- destructor PyTypeObject.tp_del
- このフィールドは非推奨です。 代わりに tp_finalize を使用してください。
- unsigned int PyTypeObject.tp_version_tag
メソッドキャッシュにインデックスを付けるために使用されます。 内部でのみ使用。
継承:
このフィールドは継承されません。
- destructor PyTypeObject.tp_finalize
インスタンスファイナライズ関数へのオプションのポインター。 その署名は次のとおりです。
void tp_finalize(PyObject *self);
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_prev
- ゼロ以外の tp_allocs フィールドを持つ前のタイプのオブジェクトへのポインター。
- PyTypeObject *PyTypeObject.tp_next
- ゼロ以外の tp_allocs フィールドを持つ次のタイプのオブジェクトへのポインター。
また、ガベージコレクションされたPythonでは、 tp_dealloc は、オブジェクトを作成したスレッドだけでなく、任意のPythonスレッドから呼び出される可能性があることに注意してください(オブジェクトがrefcountサイクルの一部になると、そのサイクルが収集される可能性があります)任意のスレッドのガベージコレクションによる)。 tp_deallocが呼び出されるスレッドがグローバルインタープリターロック(GIL)を所有するため、これはPythonAPI呼び出しの問題ではありません。 ただし、破棄されるオブジェクトが他のCまたはC ++ライブラリのオブジェクトを破棄する場合は、tp_deallocを呼び出したスレッドでそれらのオブジェクトを破棄しても、ライブラリの前提に違反しないように注意する必要があります。
ヒープタイプ
従来、Cコードで定義された型は static です。つまり、静的 PyTypeObject 構造はコードで直接定義され、 PyType_Ready()を使用して初期化されます。
これにより、Pythonで定義された型に比べて制限された型になります。
- 静的タイプは1つのベースに制限されています。 多重継承を使用することはできません。
- 静的型オブジェクト(必ずしもそのインスタンスである必要はありません)は不変です。 Pythonから型オブジェクトの属性を追加または変更することはできません。
- 静的型オブジェクトはサブインタープリター間で共有されるため、サブインタープリター固有の状態を含めることはできません。
また、 PyTypeObject は stable ABI の一部ではないため、静的型を使用する拡張モジュールは、特定のPythonマイナーバージョン用にコンパイルする必要があります。
静的型の代わりに、ヒープ割り当て型、または略してヒープ型があります。これは、Pythonのclass
ステートメントによって作成されたクラスに密接に対応します。
これは、 PyType_Spec 構造体に入力し、 PyType_FromSpecWithBases()を呼び出すことによって行われます。
番号オブジェクト構造
- type PyNumberMethods
この構造体は、オブジェクトが数値プロトコルを実装するために使用する関数へのポインターを保持します。 各関数は、番号プロトコルセクションに記載されている同様の名前の関数によって使用されます。
構造の定義は次のとおりです。
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;
ノート
バイナリ関数とターナリ関数は、すべてのオペランドの型をチェックし、必要な変換を実装する必要があります(オペランドの少なくとも1つは定義された型のインスタンスです)。 指定されたオペランドに対して演算が定義されていない場合、2進関数と3進関数は
Py_NotImplemented
を返す必要があり、別のエラーが発生した場合はNULL
を返して例外を設定する必要があります。ノート
nb_reserved フィールドは常に
NULL
である必要があります。 以前はnb_long
と呼ばれていましたが、Python3.0.1で名前が変更されました。
- binaryfunc PyNumberMethods.nb_add
- binaryfunc PyNumberMethods.nb_subtract
- binaryfunc PyNumberMethods.nb_multiply
- binaryfunc PyNumberMethods.nb_remainder
- binaryfunc PyNumberMethods.nb_divmod
- ternaryfunc PyNumberMethods.nb_power
- unaryfunc PyNumberMethods.nb_negative
- unaryfunc PyNumberMethods.nb_positive
- unaryfunc PyNumberMethods.nb_absolute
- inquiry PyNumberMethods.nb_bool
- unaryfunc PyNumberMethods.nb_invert
- binaryfunc PyNumberMethods.nb_lshift
- binaryfunc PyNumberMethods.nb_rshift
- binaryfunc PyNumberMethods.nb_and
- binaryfunc PyNumberMethods.nb_xor
- binaryfunc PyNumberMethods.nb_or
- unaryfunc PyNumberMethods.nb_int
- void *PyNumberMethods.nb_reserved
- unaryfunc PyNumberMethods.nb_float
- binaryfunc PyNumberMethods.nb_inplace_add
- binaryfunc PyNumberMethods.nb_inplace_subtract
- binaryfunc PyNumberMethods.nb_inplace_multiply
- binaryfunc PyNumberMethods.nb_inplace_remainder
- ternaryfunc PyNumberMethods.nb_inplace_power
- binaryfunc PyNumberMethods.nb_inplace_lshift
- binaryfunc PyNumberMethods.nb_inplace_rshift
- binaryfunc PyNumberMethods.nb_inplace_and
- binaryfunc PyNumberMethods.nb_inplace_xor
- binaryfunc PyNumberMethods.nb_inplace_or
- binaryfunc PyNumberMethods.nb_floor_divide
- binaryfunc PyNumberMethods.nb_true_divide
- binaryfunc PyNumberMethods.nb_inplace_floor_divide
- binaryfunc PyNumberMethods.nb_inplace_true_divide
- unaryfunc PyNumberMethods.nb_index
- binaryfunc PyNumberMethods.nb_matrix_multiply
- binaryfunc PyNumberMethods.nb_inplace_matrix_multiply
オブジェクト構造のマッピング
- type PyMappingMethods
- この構造体は、オブジェクトがマッピングプロトコルを実装するために使用する関数へのポインタを保持します。 3つのメンバーがあります。
- lenfunc PyMappingMethods.mp_length
- この関数は PyMapping_Size()と PyObject_Size()によって使用され、同じ署名を持っています。 オブジェクトの長さが定義されていない場合、このスロットは
NULL
に設定できます。
- binaryfunc PyMappingMethods.mp_subscript
- この関数は、 PyObject_GetItem()および PySequence_GetSlice()によって使用され、!PyObject_GetItem と同じ署名を持ちます。 PyMapping_Check()関数が
1
を返すには、このスロットを埋める必要があります。それ以外の場合は、NULL
にすることができます。
- objobjargproc PyMappingMethods.mp_ass_subscript
- この関数は、 PyObject_SetItem()、 PyObject_DelItem()、
PyObject_SetSlice()
、およびPyObject_DelSlice()
によって使用されます。 !PyObject_SetItem と同じ署名がありますが、 v をNULL
に設定してアイテムを削除することもできます。 このスロットがNULL
の場合、オブジェクトはアイテムの割り当てと削除をサポートしていません。
シーケンスオブジェクトの構造
- type PySequenceMethods
- この構造体は、オブジェクトがシーケンスプロトコルを実装するために使用する関数へのポインタを保持します。
- lenfunc PySequenceMethods.sq_length
- この関数は PySequence_Size()と PyObject_Size()によって使用され、同じ署名を持っています。 また、 sq_item および sq_ass_item スロットを介して負のインデックスを処理するためにも使用されます。
- binaryfunc PySequenceMethods.sq_concat
- この関数は PySequence_Concat()によって使用され、同じ署名を持っています。 nb_add スロットを介して数値加算を試みた後、
+
オペレーターによっても使用されます。
- ssizeargfunc PySequenceMethods.sq_repeat
- この関数は PySequence_Repeat()によって使用され、同じ署名を持っています。 nb_multiply スロットを介して数値の乗算を試みた後、
*
演算子によっても使用されます。
- ssizeargfunc PySequenceMethods.sq_item
この関数は PySequence_GetItem()によって使用され、同じ署名を持っています。 mp_subscript スロットを介してサブスクリプションを試行した後、 PyObject_GetItem()によっても使用されます。 PySequence_Check()関数が
1
を返すには、このスロットを埋める必要があります。それ以外の場合は、NULL
にすることができます。負のインデックスは次のように処理されます。
sq_length
スロットがいっぱいになると、それが呼び出され、シーケンス長を使用してsq_item
に渡される正のインデックスが計算されます。sq_length
がNULL
の場合、インデックスはそのまま関数に渡されます。
- ssizeobjargproc PySequenceMethods.sq_ass_item
- この関数は PySequence_SetItem()によって使用され、同じ署名を持っています。 mp_ass_subscript スロットを介してアイテムの割り当てと削除を試みた後、 PyObject_SetItem()および PyObject_DelItem()でも使用されます。 オブジェクトがアイテムの割り当てと削除をサポートしていない場合、このスロットは
NULL
のままにしておくことができます。
- objobjproc PySequenceMethods.sq_contains
- この関数は PySequence_Contains()で使用でき、同じ署名があります。 このスロットは
NULL
のままにしておくことができます。この場合、!PySequence_Contains は、一致するものが見つかるまでシーケンスをトラバースするだけです。
- binaryfunc PySequenceMethods.sq_inplace_concat
- この関数は PySequence_InPlaceConcat()によって使用され、同じ署名を持っています。 最初のオペランドを変更して返す必要があります。 このスロットは
NULL
のままにしておくことができます。この場合、!PySequence_InPlaceConcat は PySequence_Concat()にフォールバックします。 また、 nb_inplace_add スロットを介して数値のインプレース加算を試みた後、拡張代入+=
によっても使用されます。
- ssizeargfunc PySequenceMethods.sq_inplace_repeat
- この関数は PySequence_InPlaceRepeat()によって使用され、同じ署名を持っています。 最初のオペランドを変更して返す必要があります。 このスロットは
NULL
のままにしておくことができます。この場合、!PySequence_InPlaceRepeat は PySequence_Repeat()にフォールバックします。 また、 nb_inplace_multiply スロットを介して数値のインプレース乗算を試行した後、拡張代入*=
によっても使用されます。
バッファオブジェクトの構造
- type PyBufferProcs
- この構造体は、バッファプロトコルに必要な関数へのポインタを保持します。 プロトコルは、エクスポータオブジェクトがその内部データをコンシューマオブジェクトに公開する方法を定義します。
- getbufferproc PyBufferProcs.bf_getbuffer
この関数のシグネチャは次のとおりです。
int (PyObject *exporter, Py_buffer *view, int flags);
flags で指定されているように、 exporter へのリクエストを処理して view に入力します。 ポイント(3)を除いて、この関数の実装は次の手順を実行する必要があります。
リクエストに対応できるか確認してください。 そうでない場合は、
PyExc_BufferError
を上げ、 view-> obj をNULL
に設定して、-1
を返します。要求されたフィールドに入力します。
エクスポート数の内部カウンターをインクリメントします。
view-> obj を exporter に設定し、 view-> obj をインクリメントします。
0
を返します。
exporter がバッファープロバイダーのチェーンまたはツリーの一部である場合、2つの主要なスキームを使用できます。
再エクスポート:ツリーの各メンバーはエクスポートオブジェクトとして機能し、 view-> obj をそれ自体への新しい参照に設定します。
リダイレクト:バッファ要求はツリーのルートオブジェクトにリダイレクトされます。 ここで、 view-> obj はルートオブジェクトへの新しい参照になります。
ビューの個々のフィールドについては、セクションバッファ構造で説明しています。エクスポータが特定のリクエストにどのように対応する必要があるかについてのルールは、セクションバッファリクエストタイプにあります。
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
の場合があります。 それ以外の場合、この関数の標準実装は次のオプションの手順を実行します。エクスポート数の内部カウンターをデクリメントします。
カウンタが
0
の場合、ビューに関連付けられているすべてのメモリを解放します。
エクスポータは、 internal フィールドを使用して、バッファ固有のリソースを追跡する必要があります。 このフィールドは一定のままであることが保証されていますが、コンシューマーは元のバッファーのコピーを view 引数として渡すことができます(MAY)。
この関数は、 view-> obj をデクリメントしてはなりません。これは、 PyBuffer_Release()で自動的に行われるためです(このスキームは、参照サイクルを中断するのに役立ちます)。
PyBuffer_Release()は、この関数をラップするコンシューマー用のインターフェースです。
非同期オブジェクト構造
バージョン3.5の新機能。
- type 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
を返す必要があります。オブジェクトが待機可能でない場合、このスロットは
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
に設定できます。
スロットタイプtypedefs
- typedef PyObject *(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems)
この関数の目的は、メモリ割り当てをメモリ初期化から分離することです。 インスタンスに適切な長さのメモリブロックへのポインタを返し、適切に配置され、ゼロに初期化されますが、
ob_refcnt
は1
に設定され、ob_type
はに設定されます。 type引数。 タイプの tp_itemsize がゼロ以外の場合、オブジェクトのob_size
フィールドは nitems に初期化され、割り当てられたメモリブロックの長さはtp_basicsize + nitems*tp_itemsize
である必要があります。 ]、sizeof(void*)
の倍数に切り上げられます。 それ以外の場合、 nitems は使用されず、ブロックの長さは tp_basicsize である必要があります。この関数は、追加のメモリを割り当てる場合でも、他のインスタンスの初期化を行うべきではありません。 これは tp_new で行う必要があります。
- typedef void (*destructor)(PyObject*)
- typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
tp_vectorcall_offset を参照してください。
vectorcallfunc
の引数は、 _PyObject_Vectorcall()の引数と同じです。バージョン3.8の新機能。
- typedef void (*freefunc)(void*)
- tp_free を参照してください。
- tp_new を参照してください。
- tp_init を参照してください。
- tp_repr を参照してください。
- オブジェクトの名前付き属性の値を返します。
- オブジェクトの名前付き属性の値を設定します。 属性を削除するには、value引数を
NULL
に設定します。
- typedef PyObject *(*getattrofunc)(PyObject *self, PyObject *attr)
オブジェクトの名前付き属性の値を返します。
tp_getattro を参照してください。
- typedef int (*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value)
オブジェクトの名前付き属性の値を設定します。 属性を削除するには、value引数を
NULL
に設定します。tp_setattro を参照してください。
tp_descrget
を参照してください。
tp_descrset
を参照してください。
- typedef Py_hash_t (*hashfunc)(PyObject*)
- tp_hash を参照してください。
- tp_richcompare を参照してください。
- tp_iter を参照してください。
- tp_iternext を参照してください。
- typedef Py_ssize_t (*lenfunc)(PyObject*)
- typedef int (*ssizeobjargproc)(PyObject*, Py_ssize_t)
例
以下は、Python型定義の簡単な例です。 それらはあなたが遭遇するかもしれない一般的な使用法を含みます。 トリッキーなコーナーケースを示すものもあります。 その他の例、実用的な情報、およびチュートリアルについては、拡張タイプの定義:チュートリアルおよび拡張タイプの定義:さまざまなトピックを参照してください。
基本的な静的タイプ:
typedef struct {
PyObject_HEAD
const char *data;
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
.tp_basicsize = sizeof(MyObject),
.tp_doc = "My objects",
.tp_new = myobj_new,
.tp_dealloc = (destructor)myobj_dealloc,
.tp_repr = (reprfunc)myobj_repr,
};
より詳細なイニシャライザーを備えた古いコード(特にCPythonコードベース)もあります。
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"mymod.MyObject", /* tp_name */
sizeof(MyObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)myobj_dealloc, /* tp_dealloc */
0, /* tp_vectorcall_offset */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_async */
(reprfunc)myobj_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
0, /* tp_flags */
"My objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
myobj_new, /* tp_new */
};
weakref、インスタンスdict、およびハッシュをサポートするタイプ:
typedef struct {
PyObject_HEAD
const char *data;
PyObject *inst_dict;
PyObject *weakreflist;
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
.tp_basicsize = sizeof(MyObject),
.tp_doc = "My objects",
.tp_weaklistoffset = offsetof(MyObject, weakreflist),
.tp_dictoffset = offsetof(MyObject, inst_dict),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
.tp_new = myobj_new,
.tp_traverse = (traverseproc)myobj_traverse,
.tp_clear = (inquiry)myobj_clear,
.tp_alloc = PyType_GenericNew,
.tp_dealloc = (destructor)myobj_dealloc,
.tp_repr = (reprfunc)myobj_repr,
.tp_hash = (hashfunc)myobj_hash,
.tp_richcompare = PyBaseObject_Type.tp_richcompare,
};
サブクラス化できず、インスタンスを作成するために呼び出すことができないstrサブクラス(例: 別のファクトリ関数を使用します):
typedef struct {
PyUnicodeObject raw;
char *extra;
} MyStr;
static PyTypeObject MyStr_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyStr",
.tp_basicsize = sizeof(MyStr),
.tp_base = NULL, // set to &PyUnicode_Type in module init
.tp_doc = "my custom str",
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_new = NULL,
.tp_repr = (reprfunc)myobj_repr,
};
最も単純な静的タイプ(固定長のインスタンスを使用):
typedef struct {
PyObject_HEAD
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
};
最も単純な静的型(可変長インスタンスを使用):
typedef struct {
PyObject_VAR_HEAD
const char *data[1];
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
.tp_basicsize = sizeof(MyObject) - sizeof(char *),
.tp_itemsize = sizeof(char *),
};