共通のオブジェクト構造体 (common object structure)¶
Python では、オブジェクト型を定義する上で数多くの構造体が使われます。この節では三つの構造体とその利用方法について説明します。
全ての Python オブジェクトは、オブジェクトのメモリ内表現の先頭部分にある少数のフィールドを完全に共有しています。
このフィールドは PyObject
型および PyVarObject
型で表現されます。
これらの型もまた、他の全ての Python オブジェクトの定義で直接または間接的に使われているマクロを使って定義されています。
-
PyObject
¶ 全てのオブジェクト型はこの型を拡張したものです。 この型には、あるオブジェクトを指すポインタをオブジェクトとして Python から扱うのに必要な情報が入っています。 通常の "リリース" ビルドでは、この構造体にはオブジェクトの参照カウントとオブジェクトに対応する型オブジェクトだけが入っています。 実際には
PyObject
であることは宣言されていませんが、全ての Python オブジェクトへのポインタはPyObject*
へキャストできます。 メンバにアクセスするにはPy_REFCNT
マクロとPy_TYPE
マクロを使わなければなりません。
-
PyVarObject
¶ PyObject
を拡張して、ob_size
フィールドを追加したものです。 この構造体は、 長さ (length) の概念を持つオブジェクトだけに対して使います。 この型が Python/C API で使われることはほとんどありません。 メンバにアクセスするにはPy_REFCNT
マクロ、Py_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)
-
Py_REFCNT
(o)¶ Python オブジェクトの
ob_refcnt
メンバにアクセスするのに使うマクロです。 これは次のように展開されます:(((PyObject*)(o))->ob_refcnt)
-
Py_SIZE
(o)¶ Python オブジェクトの
ob_size
メンバにアクセスするのに使うマクロです。 これは次のように展開されます:(((PyVarObject*)(o))->ob_size)
-
PyObject_HEAD_INIT
(type)¶ 新しい
PyObject
型のための初期値に展開するマクロです。このマクロは次のように展開されます。_PyObject_EXTRA_INIT 1, type,
-
PyVarObject_HEAD_INIT
(type, size)¶ 新しい、
ob_size
フィールドを含むPyVarObject
型のための初期値に展開するマクロです。このマクロは次のように展開されます。_PyObject_EXTRA_INIT 1, type, size,
-
PyCFunction
¶ ほとんどの Python の呼び出し可能オブジェクトを C で実装する際に用いられている関数の型です。この型の関数は 2 つの
PyObject*
型のパラメータを取り、 PyObject* 型の値を返します。戻り値を NULL にする場合、例外をセットしておかなければなりません。 NULL でない値を返す場合、戻り値は Python に関数の戻り値として公開される値として解釈されます。この型の関数は新たな参照を返さなければなりません。
-
PyCFunctionWithKeywords
¶ キーワード引数をとるPythonの呼び出し可能オブジェクトを C で実装する際に用いられている関数の型です: この型の関数は 3 つの
PyObject*
型のパラメータをとり、 PyObject* 型の値を返します。戻り値の意味については、上記のPyCFunction
を参照して下さい。
-
PyMethodDef
¶ 拡張型のメソッドを記述する際に用いる構造体です。この構造体には 4 つのフィールドがあります:
フィールド C の型 意味 ml_name
char * メソッド名 ml_meth
PyCFunction C 実装へのポインタ ml_flags
int 呼び出しをどのように行うかを示すフラグビット ml_doc
char * docstring の内容を指すポインタ
ml_meth
は C の関数ポインタです。関数は別の型で定義されていてもかまいませんが、常に PyObject*
を返します。関数が PyFunction
でない場合、メソッドテーブル内でキャストを行うようコンパイラが要求することになるでしょう。 PyCFunction
では最初のパラメタが PyObject*
型であると定義していますが、固有の C 型を self オブジェクトに使う実装はよく行われています。
ml_flags
フィールドはビットフィールドで、以下のフラグが入ります。
個々のフラグは呼び出し規約 (calling convention) や束縛規約 (binding convention) を表します。
呼び出し規約フラグでは、 METH_VARARGS
および METH_KEYWORDS
だけが組み合わせられます。
呼び出し規約フラグは束縛規約フラグと組み合わせられます。
-
METH_VARARGS
¶ PyCFunction
型のメソッドで典型的に使われる呼び出し規約です。関数はPyObject*
型の引数値を二つ要求します。最初の引数はメソッドの self オブジェクトです; モジュール関数の場合、これはモジュールオブジェクトです。第二のパラメタ (よく args と呼ばれます) は、全ての引数を表現するタプルオブジェクトです。パラメタは通常、PyArg_ParseTuple()
やPyArg_UnpackTuple()
で処理されます。
-
METH_KEYWORDS
¶ このフラグを持つメソッドは
PyCFunctionWithKeywords
型でなければなりません。 この関数は 3 つのパラメータを要求します: self 、 args 、およびキーワード引数全てからなる辞書です。 このフラグはMETH_VARARGS
と組み合わせて用いられなければならず、パラメタは通常PyArg_ParseTupleAndKeywords()
で処理されます。
-
METH_NOARGS
¶ 引数のないメソッドは、
METH_NOARGS
フラグをつけた場合、必要な引数が指定されているかをチェックしなくなります。こうしたメソッドはPyCFunction
型でなくてはなりません。第一のパラメタは self になり、モジュールかオブジェクトインスタンスへの参照を保持することになります。いずれにせよ、第二のパラメタは NULL になります。
-
METH_O
¶ 単一のオブジェクト引数だけをとるメソッドは、
PyArg_ParseTuple()
を引数"O"
にして呼び出す代わりに、METH_O
フラグつきで指定できます。メソッドはPyCFunction
型で、 self パラメタと単一の引数を表現するPyObject*
パラメタを伴います。
以下の二つの定数は、呼び出し規約を示すものではなく、クラスのメソッドとして使う際の束縛方式を示すものです。モジュールに対して定義された関数で用いてはなりません。メソッドに対しては、最大で一つしかこのフラグをセットできません。
-
METH_CLASS
¶ メソッドの最初の引数には、型のインスタンスではなく型オブジェクトが渡されます。このフラグは組み込み関数
classmethod()
を使って生成するのと同じ クラスメソッド (class method) を生成するために使われます。
-
METH_STATIC
¶ メソッドの最初の引数には、型のインスタンスではなく NULL が渡されます。このフラグは、
staticmethod()
を使って生成するのと同じ 静的メソッド (static method) を生成するために使われます。
もう一つの定数は、あるメソッドを同名の別のメソッド定義と置き換えるかどうかを制御します。
-
METH_COEXIST
¶ メソッドを既存の定義を置き換える形でロードします。 METH_COEXIST を指定しなければ、デフォルトの設定にしたがって、定義が重複しないようスキップします。スロットラッパはメソッドテーブルよりも前にロードされるので、例えば sq_contains スロットはラップしているメソッド
__contains__()
を生成し、同名の PyCFunction のロードを阻止します。このフラグを定義すると、 PyCFunction はラッパオブジェクトを置き換える形でロードされ、スロットと連立します。 PyCFunctions の呼び出しはラッパオブジェクトの呼び出しよりも最適化されているので、こうした仕様が便利になります。
-
PyMemberDef
¶ type の C 構造体のメンバとして格納されている、ある型の属性を表す構造体です。この構造体のフィールドは以下のとおりです:
フィールド C の型 意味 name
char * メンバ名 type
int C 構造体の中のメンバの型 offset
Py_ssize_t そのメンバの type object 構造体中の場所の offset バイト数 flags
int フィールドが読み出し専用か書込み可能なのかを示すビットフラグ doc
char * docstring の内容を指すポインタ type
はたくさんのCの型を意味するT_
マクロのうちの1つです。メンバが Python からアクセスされるとき、そのメンバは対応する Python の型に変換されます。マクロ名 C の型 T_SHORT short T_INT int T_LONG long T_FLOAT 浮動小数点数 T_DOUBLE double T_STRING char * T_OBJECT PyObject * T_OBJECT_EX PyObject * T_CHAR char T_BYTE char T_UBYTE unsigned char T_UINT unsigned int T_USHORT unsigned short T_ULONG unsigned long T_BOOL char T_LONGLONG long long T_ULONGLONG unsigned long long T_PYSSIZET Py_ssize_t T_OBJECT
とT_OBJECT_EX
が異なっているのは、T_OBJECT
はメンバが NULL だったときにNone
を返すのに対し、T_OBJECT_EX
はAttributeError
を送出する点です。T_OBJECT_EX
はT_OBJECT
より属性に対するdel
文を正しくあつかうので、できればT_OBJECT
ではなくT_OBJECT_EX
を使ってください。flags
には読み書きアクセス可能なら0
で、読み出し専用ならREADONLY
を設定します。type
にT_STRING
を使うと、READONLY
扱いになります。T_OBJECT
メンバとT_OBJECT_EX
メンバだけが削除できます (NULL が代入されます)。
-
PyGetSetDef
¶ Structure to define property-like access for a type. See also description of the
PyTypeObject.tp_getset
slot.フィールド C の型 意味 名前 char * attribute name get getter C Function to get the attribute 集合 setter optional C function to set or delete the attribute, if omitted the attribute is readonly doc char * optional docstring closure void * optional function pointer, providing additional data for getter and setter The
get
function takes onePyObject*
parameter (the instance) and a function pointer (the associatedclosure
):typedef PyObject *(*getter)(PyObject *, void *);
It should return a new reference on success or NULL with a set exception on failure.
set
functions take twoPyObject*
parameters (the instance and the value to be set) and a function pointer (the associatedclosure
):typedef int (*setter)(PyObject *, PyObject *, void *);
In case the attribute should be deleted the second parameter is NULL. Should return
0
on success or-1
with a set exception on failure.