### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python 2.7ja1 documentation »
- Python/C API リファレンスマニュアル »
- オブジェクト実装サポート (object implementation support) »

# 共通のオブジェクト構造体 (common object structure)

Python では、オブジェクト型を定義する上で数多くの構造体が使われます。この節では三つの構造体とその利用方法について説明します。

全ての Python オブジェクトは、オブジェクトのメモリ内表現の先頭部分にある少数のフィールドを完全に共有しています。このフィールドは `PyObject` および `PyVarObject` 型で表現されます。 `PyObject` 型や `PyVarObject` 型もまた、他の全ての Python オブジェクトを定義する上で直接的・間接的に使われているマクロを使って定義されています。

`PyObject`

  全てのオブジェクト型はこの型を拡張したものです。この型には、あるオブジェクトに対するオブジェクトとしてのポインタを Python から扱う必要がある際に必要な情報が入っています。通常に “リリースされている” ビルドでは、この構造体にはオブジェクトの参照カウントと、オブジェクトに対応する型オブジェクトだけが入っています。

  `PyObject_HEAD` マクロ展開で定義されているフィールドに対応します。

`PyVarObject`

  `PyObject` を拡張して、 `ob_size` フィールドを追加したものです。この構造体は、 長さ (length) の概念を持つオブジェクトだけに対して使います。この型が Python/C API で使われることはほとんどありません。 `PyObject_VAR_HEAD` マクロ展開で定義されているフィールドに対応します。

`PyObject` および `PyVarObject` の定義には以下のマクロが使われています:

`PyObject_HEAD`

  `PyObject` 型のフィールド宣言に展開されるマクロです; 可変でない長さを持つオブジェクトを表現する新たな型を宣言する場合に使います。展開によってどのフィールドが宣言されるかは、 `Py_TRACE_REFS` の定義に依存します。デフォルトでは、 `Py_TRACE_REFS` は定義されておらず、 `PyObject_HEAD` は以下のコードに展開されます:

      Py_ssize_t ob_refcnt;
      PyTypeObject *ob_type;

  `Py_TRACE_REFS` が定義されている場合、以下のように展開されます:

      PyObject *_ob_next, *_ob_prev;
      Py_ssize_t ob_refcnt;
      PyTypeObject *ob_type;

`PyObject_VAR_HEAD`

  マクロです。 `PyVarObject` 型のフィールド宣言に展開されるマクロです; インスタンスによって可変の長さを持つオブジェクトを表現する新たな型を宣言する場合に使います。マクロは常に以下のように展開されます:

      PyObject_HEAD
      Py_ssize_t ob_size;

  マクロ展開結果の一部に `PyObject_HEAD` が含まれており、 `PyObject_HEAD` の展開結果は `Py_TRACE_REFS` の定義に依存します。

`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 で実装する際に用いられている関数の型です。この型の関数は二つの `PyObject*` 型パラメタをとり、 `PyObject*` 型の値を返します。戻り値を NULL にする場合、例外をセットしておかなければなりません。 NULL でない値を返す場合、戻り値は Python に関数の戻り値として公開される値として解釈されます。この型の関数は新たな参照を返さなければなりません。

`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_KEYWORDS` 単体の指定を行っても `METH_VARARGS | METH_KEYWORDS` と同じなので注意してください)。呼び出し規約フラグは束縛フラグと組み合わせられます。

`METH_VARARGS`

  `PyCFunction` 型のメソッドで典型的に使われる呼び出し規約です。関数は `PyObject*` 型の引数値を二つ要求します。最初の引数はメソッドの self オブジェクトです; モジュール関数の場合、これはモジュールオブジェクトです。第二のパラメタ (よく args と呼ばれます) は、全ての引数を表現するタプルオブジェクトです。パラメタは通常、 `PyArg_ParseTuple()` や `PyArg_UnpackTuple()` で処理されます。

`METH_KEYWORDS`

  このフラグを持つメソッドは `PyCFunctionWithKeywords` 型でなければなりません。 `PyCFunctionWithKeywords` は三つのパラメタ:self 、 args 、およびキーワード引数全てからなる辞書、を要求します。このフラグは通常 `METH_VARARGS` と組み合わされ、パラメタは `PyArg_ParseTupleAndKeywords()` で処理されます。

`METH_NOARGS`

  引数のないメソッドは、 `METH_NOARGS` フラグをつけた場合、必要な引数が指定されているかをチェックしなくなります。こうしたメソッドは `PyCFunction` 型でなくてはなりません。第一のパラメタは `self` になり、モジュールかオブジェクトインスタンスへの参照を保持することになります。いずれにせよ、第二のパラメタは NULL になります。

`METH_O`

  単一のオブジェクト引数だけをとるメソッドは、 `PyArg_ParseTuple()` を引数 `"O"` にして呼び出す代わりに、 `METH_O` フラグつきで指定できます。メソッドは `PyCFunction` 型で、 self パラメタと単一の引数を表現する `PyObject*` パラメタを伴います。

`METH_OLDARGS`

  この呼び出し規約は撤廃されました。メソッドは `PyCFunction` 型でなければなりません。第二引数は、引数がない場合には NULL 、単一の引数の場合にはその引数オブジェクト、複数個の引数の場合には引数オブジェクトからなるタプルです。この呼び出し規約を使うと、複数個の引数の場合と、単一のタプルが唯一引数の場合を区別できなくなってしまいます。

以下の二つの定数は、呼び出し規約を示すものではなく、クラスのメソッドとして使う際の束縛方式を示すものです。モジュールに対して定義された関数で用いてはなりません。メソッドに対しては、最大で一つしかこのフラグをセットできません。

`METH_CLASS`

  メソッドの最初の引数には、型のインスタンスではなく型オブジェクトが渡されます。このフラグは組み込み関数 `classmethod()` を使って生成するのと同じ クラスメソッド (class method) を生成するために使われます。

  バージョン 2.3 で追加.

`METH_STATIC`

  メソッドの最初の引数には、型のインスタンスではなく NULL が渡されます。このフラグは、 `staticmethod()` を使って生成するのと同じ 静的メソッド (static method) を生成するために使われます。

  バージョン 2.3 で追加.

もう一つの定数は、あるメソッドを同名の別のメソッド定義と置き換えるかどうかを制御します。

`METH_COEXIST`

  メソッドを既存の定義を置き換える形でロードします。 METH_COEXIST を指定しなければ、デフォルトの設定にしたがって、定義が重複しないようスキップします。スロットラッパはメソッドテーブルよりも前にロードされるので、例えば sq_contains スロットはラップしているメソッド `__contains__()` を生成し、同名の PyCFunction のロードを阻止します。このフラグを定義すると、 PyCFunction はラッパオブジェクトを置き換える形でロードされ、スロットと連立します。 PyCFunctions の呼び出しはラッパオブジェクトの呼び出しよりも最適化されているので、こうした仕様が便利になります。

  バージョン 2.4 で追加.

`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 | 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` は属性に対する `del` 文をより正しくあつかうので、できれば `T_OBJECT` よりも `T_OBJECT_EX` を使ってください。

  `flags` には読み書きアクセス可能なら 0 で、読み込み専用なら `READONLY` を設定します。 `type` に `T_STRING` を使うと、強制的に `READONLY` 扱いになります。 `T_OBJECT` and `T_OBJECT_EX` メンバだけが del 可能です。 (NULL が代入されます).

PyObject* `Py_FindMethod`(PyMethodDef table[], PyObject *ob, char *name)
  Return value: New reference.

  C で実装された拡張型の束縛メソッドオブジェクトを返します。 `PyObject_GenericGetAttr()` 関数を使わない `tp_getattro` や `tp_getattr` ハンドラを実装する際に便利です。

### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python 2.7ja1 documentation »
- Python/C API リファレンスマニュアル »
- オブジェクト実装サポート (object implementation support) »