一般的なオブジェクト構造—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.9/c-api/structures
移動先:案内検索

一般的なオブジェクト構造

Pythonのオブジェクトタイプの定義で使用される構造は多数あります。 このセクションでは、これらの構造とその使用方法について説明します。

基本オブジェクトタイプとマクロ

すべてのPythonオブジェクトは、最終的に、メモリ内のオブジェクトの表現の先頭で少数のフィールドを共有します。 これらは、 PyObject および PyVarObject タイプによって表されます。これらは、他のすべてのPythonの定義で、直接的または間接的に使用されるいくつかのマクロの展開によって定義されます。オブジェクト。

type PyObject
すべてのオブジェクトタイプは、このタイプの拡張です。 これは、Pythonがオブジェクトへのポインタをオブジェクトとして扱うために必要な情報を含むタイプです。 通常の「リリース」ビルドでは、オブジェクトの参照カウントと対応するタイプオブジェクトへのポインタのみが含まれます。 実際には PyObject として宣言されているものはありませんが、Pythonオブジェクトへのすべてのポインターを PyObject * にキャストできます。 メンバーへのアクセスは、マクロ Py_REFCNT および Py_TYPE を使用して行う必要があります。
type PyVarObject
これは PyObject の拡張であり、ob_sizeフィールドを追加します。 これは、長さの概念を持つオブジェクトにのみ使用されます。 このタイプは、Python / CAPIにはあまり表示されません。 メンバーへのアクセスは、マクロ Py_REFCNTPy_TYPE 、および Py_SIZE を使用して行う必要があります。
PyObject_HEAD

これは、長さを変えずにオブジェクトを表す新しい型を宣言するときに使用されるマクロです。 PyObject_HEADマクロは次のように展開されます。

PyObject ob_base;

上記の PyObject のドキュメントを参照してください。

PyObject_VAR_HEAD

これは、インスタンスごとに異なる長さのオブジェクトを表す新しい型を宣言するときに使用されるマクロです。 PyObject_VAR_HEADマクロは次のように展開されます。

PyVarObject ob_base;

上記の PyVarObject のドキュメントを参照してください。

Py_TYPE(o)

このマクロは、Pythonオブジェクトのob_typeメンバーにアクセスするために使用されます。 次のように展開されます。

(((PyObject*)(o))->ob_type)
int Py_IS_TYPE(PyObject *o, PyTypeObject *type)

オブジェクト o タイプがタイプの場合、ゼロ以外を返します。 それ以外の場合はゼロを返します。 Py_TYPE(o) == typeと同等です。

バージョン3.9の新機能。

void Py_SET_TYPE(PyObject *o, PyTypeObject *type)

オブジェクト o タイプをタイプに設定します。

バージョン3.9の新機能。

Py_REFCNT(o)

このマクロは、Pythonオブジェクトのob_refcntメンバーにアクセスするために使用されます。 次のように展開されます。

(((PyObject*)(o))->ob_refcnt)
void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)

オブジェクト o 参照カウンターを refcnt に設定します。

バージョン3.9の新機能。

Py_SIZE(o)

このマクロは、Pythonオブジェクトのob_sizeメンバーにアクセスするために使用されます。 次のように展開されます。

(((PyVarObject*)(o))->ob_size)
void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size)

オブジェクトの o サイズをサイズに設定します。

バージョン3.9の新機能。

PyObject_HEAD_INIT(type)

これは、新しい PyObject タイプの初期化値に展開されるマクロです。 このマクロは次のように展開されます。

_PyObject_EXTRA_INIT
1, type,
PyVarObject_HEAD_INIT(type, size)

これは、ob_sizeフィールドを含む新しい PyVarObject タイプの初期化値に展開されるマクロです。 このマクロは次のように展開されます。

_PyObject_EXTRA_INIT
1, type, size,


関数とメソッドの実装

type PyCFunction

ほとんどのPython呼び出し可能オブジェクトをCで実装するために使用される関数のタイプ。 このタイプの関数は、2つの PyObject * パラメーターを受け取り、そのような値を1つ返します。 戻り値がNULLの場合、例外が設定されている必要があります。 NULLでない場合、戻り値はPythonで公開されている関数の戻り値として解釈されます。 関数は新しい参照を返す必要があります。

関数のシグネチャは次のとおりです。

PyObject *PyCFunction(PyObject *self,
                      PyObject *args);
type PyCFunctionWithKeywords

シグニチャMETH_VARARGS | METH_KEYWORDSを使用してCでPython呼び出し可能オブジェクトを実装するために使用される関数のタイプ。 関数のシグネチャは次のとおりです。

PyObject *PyCFunctionWithKeywords(PyObject *self,
                                  PyObject *args,
                                  PyObject *kwargs);
type _PyCFunctionFast

シグニチャ METH_FASTCALL を使用してCでPython呼び出し可能オブジェクトを実装するために使用される関数のタイプ。 関数のシグネチャは次のとおりです。

PyObject *_PyCFunctionFast(PyObject *self,
                           PyObject *const *args,
                           Py_ssize_t nargs);
type _PyCFunctionFastWithKeywords

シグニチャMETH_FASTCALL | METH_KEYWORDSを使用してCでPython呼び出し可能オブジェクトを実装するために使用される関数のタイプ。 関数のシグネチャは次のとおりです。

PyObject *_PyCFunctionFastWithKeywords(PyObject *self,
                                       PyObject *const *args,
                                       Py_ssize_t nargs,
                                       PyObject *kwnames);
type PyCMethod

シグニチャMETH_METHOD | METH_FASTCALL | METH_KEYWORDSを使用してCでPython呼び出し可能オブジェクトを実装するために使用される関数のタイプ。 関数のシグネチャは次のとおりです。

PyObject *PyCMethod(PyObject *self,
                    PyTypeObject *defining_class,
                    PyObject *const *args,
                    Py_ssize_t nargs,
                    PyObject *kwnames)

バージョン3.9の新機能。

type PyMethodDef

拡張タイプのメソッドを記述するために使用される構造。 この構造には4つのフィールドがあります。

分野

Cタイプ

意味

ml_name

const char *

メソッドの名前

ml_meth

PyCFunction

C実装へのポインタ

ml_flags

int

呼び出しの構成方法を示すフラグビット

ml_doc

const char *

docstringの内容を指します

ml_methはC関数ポインタです。 関数はさまざまなタイプである可能性がありますが、常に PyObject * を返します。 関数が PyCFunction のものでない場合、コンパイラーはメソッドテーブルでのキャストを必要とします。 PyCFunction は最初のパラメーターを PyObject * として定義していますが、メソッドの実装では self オブジェクトの特定のCタイプを使用するのが一般的です。

ml_flagsフィールドは、次のフラグを含めることができるビットフィールドです。 個々のフラグは、呼び出し規約またはバインディング規約のいずれかを示します。

これらの呼び出し規約があります:

METH_VARARGS
これは典型的な呼び出し規約であり、メソッドのタイプは PyCFunction です。 この関数は、2つの PyObject * 値を想定しています。 1つ目は、メソッドの self オブジェクトです。 モジュール関数の場合、これはモジュールオブジェクトです。 2番目のパラメーター( args と呼ばれることが多い)は、すべての引数を表すタプルオブジェクトです。 このパラメーターは通常、 PyArg_ParseTuple()または PyArg_UnpackTuple()を使用して処理されます。
METH_VARARGS | METH_KEYWORDS
これらのフラグを持つメソッドは、タイプ PyCFunctionWithKeywords である必要があります。 この関数は、 selfargskwargs の3つのパラメーターを必要とします。ここで、 kwargs は、すべてのキーワード引数または場合によってはNULLキーワード引数がない場合。 パラメータは通常、 PyArg_ParseTupleAndKeywords()を使用して処理されます。
METH_FASTCALL

位置引数のみをサポートする高速呼び出し規約。 メソッドのタイプは _PyCFunctionFast です。 最初のパラメーターは self 、2番目のパラメーターは引数を示す PyObject * 値のC配列、3番目のパラメーターは引数の数(配列の長さ)です。

これは限定API の一部ではありません。

バージョン3.7の新機能。

METH_FASTCALL | METH_KEYWORDS

タイプ _PyCFunctionFastWithKeywords のメソッドを使用して、キーワード引数もサポートする METH_FASTCALL の拡張。 キーワード引数は、 vectorcallプロトコルと同じ方法で渡されます。追加の4番目の PyObject * パラメーターがあります。これは、キーワード引数の名前を表すタプルです(文字列)またはキーワードがない場合はNULL。 キーワード引数の値は、位置引数の後に args 配列に格納されます。

これは限定API の一部ではありません。

バージョン3.7の新機能。

METH_METHOD | METH_FASTCALL | METH_KEYWORDS

定義クラス、つまり問題のメソッドを含むクラスをサポートするMETH_FASTCALL | METH_KEYWORDSの拡張。 定義するクラスは、Py_TYPE(self)のスーパークラスである可能性があります。

メソッドはタイプ PyCMethod である必要があります。これは、METH_FASTCALL | METH_KEYWORDSの場合と同じで、selfの後にdefining_class引数が追加されています。

バージョン3.9の新機能。

METH_NOARGS
パラメータのないメソッドは、 METH_NOARGS フラグが付いている場合、引数が指定されているかどうかを確認する必要はありません。 タイプは PyCFunction である必要があります。 最初のパラメータは通常 self という名前で、モジュールまたはオブジェクトインスタンスへの参照を保持します。 すべての場合において、2番目のパラメーターはNULLになります。
METH_O
"O"引数で PyArg_ParseTuple()を呼び出す代わりに、単一のオブジェクト引数を持つメソッドを METH_O フラグでリストできます。 タイプは PyCFunction で、 self パラメーターと、 PyObject * パラメーターが単一の引数を表します。

これらの2つの定数は、呼び出し規約を示すために使用されるのではなく、クラスのメソッドで使用する場合のバインディングを示します。 これらは、モジュール用に定義された関数には使用できません。 これらのフラグの最大1つは、任意のメソッドに設定できます。

METH_CLASS
メソッドには、型のインスタンスではなく、最初のパラメーターとして型オブジェクトが渡されます。 これは、 classmethod()組み込み関数を使用するときに作成されるものと同様に、クラスメソッドを作成するために使用されます。
METH_STATIC
メソッドには、型のインスタンスではなく、最初のパラメーターとしてNULLが渡されます。 これは、 staticmethod()組み込み関数を使用するときに作成されるものと同様に、 staticメソッドを作成するために使用されます。

もう1つの定数は、同じメソッド名を持つ別の定義の代わりにメソッドをロードするかどうかを制御します。

METH_COEXIST
メソッドは、既存の定義の代わりにロードされます。 METH_COEXIST がない場合、デフォルトでは繰り返し定義をスキップします。 スロットラッパーはメソッドテーブルの前にロードされるため、たとえば sq_contains スロットが存在すると、__contains__()という名前のラップされたメソッドが生成され、同じ名前の対応するPyCFunctionのロードができなくなります。 。 フラグを定義すると、ラッパーオブジェクトの代わりにPyCFunctionがロードされ、スロットと共存します。 PyCFunctionsの呼び出しは、ラッパーオブジェクトの呼び出しよりも最適化されているため、これは便利です。


拡張タイプの属性へのアクセス

type PyMemberDef

C構造体メンバーに対応する型の属性を記述する構造体。 そのフィールドは次のとおりです。

分野

Cタイプ

意味

name

const char *

メンバーの名前

type

int

C構造体のメンバーのタイプ

offset

Py_ssize_t

メンバーが型のオブジェクト構造体に配置されているバイト単位のオフセット

flags

int

フィールドを読み取り専用にするか書き込み可能にするかを示すフラグビット

doc

const char *

docstringの内容を指します

typeは、さまざまなCタイプに対応する多くのT_マクロの1つです。 メンバーがPythonでアクセスされると、同等のPythonタイプに変換されます。

マクロ名

Cタイプ

T_SHORT

短い

T_INT

int

T_LONG

長いです

T_FLOAT

浮く

T_DOUBLE

ダブル

T_STRING

const char *

T_OBJECT

PyObject *

T_OBJECT_EX

PyObject *

T_CHAR

char

T_BYTE

char

T_UBYTE

unsigned char

T_UINT

unsigned int

T_USHORT

署名されていない短い

T_ULONG

unsigned long

T_BOOL

char

T_LONGLONG

長い長い

T_ULONGLONG

unsigned long long

T_PYSSIZET

Py_ssize_t

T_OBJECTT_OBJECT_EXは、メンバーがNULLの場合、T_OBJECTNoneを返し、T_OBJECT_EXを上げるという点で異なります。 ] AttributeErrorT_OBJECT_EXT_OBJECTよりもその属性での del ステートメントの使用をより正確に処理するため、T_OBJECTではなくT_OBJECT_EXを使用してみてください。

flagsは、書き込みおよび読み取りアクセスの場合は0、読み取り専用アクセスの場合はREADONLYになります。 タイプT_STRINGを使用すると、READONLYを意味します。 T_STRINGデータはUTF-8として解釈されます。 T_OBJECTおよびT_OBJECT_EXメンバーのみを削除できます。 (NULLに設定されています)。

ヒープ割り当てタイプ( PyType_FromSpec()などを使用して作成)、PyMemberDefには、特別なメンバー__dictoffset____weaklistoffset__、および [の定義が含まれる場合があります。 X163X]、タイプオブジェクトの tp_dictoffsettp_weaklistoffset 、および tp_vectorcall_offset に対応します。 これらは、T_PYSSIZETおよびREADONLYで定義する必要があります。次に例を示します。

static PyMemberDef spam_type_members[] = {
    {"__dictoffset__", T_PYSSIZET, offsetof(Spam_object, dict), READONLY},
    {NULL}  /* Sentinel */
};
PyObject *PyMember_GetOne(const char *obj_addr, struct PyMemberDef *m)
アドレス obj_addr のオブジェクトに属する属性を取得します。 属性はPyMemberDef m で記述されます。 エラー時にNULLを返します。
int PyMember_SetOne(char *obj_addr, struct PyMemberDef *m, PyObject *o)
アドレス obj_addr のオブジェクトに属する属性をオブジェクト o に設定します。 設定する属性はPyMemberDef m で記述されています。 成功した場合は0を返し、失敗した場合は負の値を返します。
type PyGetSetDef

タイプのプロパティのようなアクセスを定義する構造。 PyTypeObject.tp_getset スロットの説明も参照してください。

分野

Cタイプ

意味

名前

const char *

属性名

得る

ゲッター

属性を取得するC関数

設定

セッター

属性を設定または削除するオプションのC関数。省略した場合、属性は読み取り専用です。

doc

const char *

オプションのdocstring

閉鎖

空所 *

オプションの関数ポインタ。ゲッターとセッターに追加データを提供します

get関数は、1つの PyObject * パラメーター(インスタンス)と関数ポインター(関連するclosure)を取ります。

typedef PyObject *(*getter)(PyObject *, void *);

成功した場合は新しい参照を返すか、失敗した場合は例外を設定してNULLを返す必要があります。

set関数は、2つの PyObject * パラメーター(インスタンスと設定する値)と関数ポインター(関連するclosure)を取ります。

typedef int (*setter)(PyObject *, PyObject *, void *);

属性を削除する必要がある場合、2番目のパラメーターはNULLです。 成功した場合は0を返し、失敗した場合は例外を設定して-1を返す必要があります。