モジュールオブジェクト (module object)¶
-
PyTypeObject
PyModule_Type
¶ この
PyTypeObject
のインスタンスは Python のモジュールオブジェクト型を表現します。このオブジェクトは、Python プログラムにはtypes.ModuleType
として公開されています。
-
int
PyModule_CheckExact
(PyObject *p)¶ p がモジュールオブジェクトで、かつモジュールオブジェクトのサブタイプでないときに真を返します。
PyModule_Type
.
-
PyObject*
PyModule_NewObject
(PyObject *name)¶ __name__
属性に name が設定された新しいモジュールオブジェクトを返します。 モジュールの__name__
,__doc__
,__package__
,__loader__
属性に値が入っています (__name__
以外は全てNone
です);__file__
属性に値を入れるのは呼び出し側の責任です。バージョン 3.3 で追加.
バージョン 3.4 で変更:
__package__
と__loader__
はNone
に設定されます。
-
PyObject*
PyModule_New
(const char *name)¶ - Return value: New reference.
Similar to
PyModule_NewObject()
, but the name is a UTF-8 encoded string instead of a Unicode object.
-
PyObject*
PyModule_GetDict
(PyObject *module)¶ - Return value: Borrowed reference.
module の名前空間を実装する辞書オブジェクトを返します; このオブジェクトは、モジュールオブジェクトの
__dict__
属性と同じものです。 module がモジュールオブジェクト (もしくはモジュールオブジェクトのサブタイプ) でない場合は、SystemError
が送出され NULL が返されます。拡張モジュールでは、モジュールの
__dict__
を直接操作するよりも、PyModule_*()
およびPyObject_*()
関数を使う方が推奨されます。
-
PyObject*
PyModule_GetNameObject
(PyObject *module)¶ module の
__name__
の値を返します。モジュールがこの属性を提供していない場合や文字列型でない場合、SystemError
を送出して NULL を返します。バージョン 3.3 で追加.
-
char*
PyModule_GetName
(PyObject *module)¶ PyModule_GetNameObject()
に似ていますが、'utf-8'
でエンコードされた name を返します。
-
void*
PyModule_GetState
(PyObject *module)¶ モジュールの "state"(モジュールを生成したタイミングで確保されるメモリブロックへのポインター) か、なければ NULL を返します。
PyModuleDef.m_size
を参照してください。
-
PyModuleDef*
PyModule_GetDef
(PyObject *module)¶ モジュールが作られる元となった
PyModuleDef
構造体へのポインタを返します。 モジュールが定義によって作られていなかった場合は NULL を返します。
-
PyObject*
PyModule_GetFilenameObject
(PyObject *module)¶ module の
__file__
属性をもとに module がロードされたもとのファイル名を返します。もしファイル名が定義されていない場合や、 Unicode 文字列ではない場合、SystemError
を発生させて NULL を返します。それ以外の場合は Unicode オブジェクトへの参照を返します。バージョン 3.2 で追加.
-
char*
PyModule_GetFilename
(PyObject *module)¶ PyModule_GetFilenameObject()
と似ていますが、 'utf-8' でエンコードされたファイル名を返します。バージョン 3.2 で撤廃:
PyModule_GetFilename()
はエンコードできないファイル名に対してはUnicodeEncodeError
を送出します。これの代わりにPyModule_GetFilenameObject()
を使用してください。
Cモジュールの初期化¶
通常、モジュールオブジェクトは拡張モジュール (初期化関数をエクスポートしている共有ライブラリ) または組み込まれたモジュール (PyImport_AppendInittab()
を使って初期化関数が追加されているモジュール) から作られます。
詳細については C および C++ 拡張のビルド または 埋め込まれた Python の拡張 を見てください。
初期化関数は、モジュール定義のインスタンスを PyModule_Create()
に渡して出来上がったモジュールオブジェクトを返してもよいですし、もしくは定義構造体そのものを返し"多段階初期化"を要求しても構いません。
-
PyModuleDef
¶ モジュール定義構造体はモジュールオブジェクトを生成するのに必要なすべての情報を保持します。 通常は、それぞれのモジュールごとに静的に初期化されたこの型の変数が1つだけ存在します。
-
PyModuleDef_Base
m_base
¶ このメンバーは常に
PyModuleDef_HEAD_INIT
で初期化してください。
-
char*
m_name
¶ 新しいモジュールの名前。
-
char*
m_doc
¶ モジュールの docstring。たいてい docstring は
PyDoc_STRVAR()
を利用して生成されます。
-
Py_ssize_t
m_size
¶ モジュールの状態は、静的なグローバルな領域ではなく
PyModule_GetState()
で取得できるモジュールごとのメモリ領域に保持されていることがあります。 これによってモジュールは複数のサブ・インタプリターで安全に使えます。このメモリ領域は m_size に基づいてモジュール作成時に確保され、モジュールオブジェクトが破棄されるときに、
m_free
関数があればそれが呼ばれた後で解放されます。m_size
に-1
を設定すると、そのモジュールはグローバルな状態を持つためにサブ・インタープリターをサポートしていないということになります。m_size
を非負の値に設定すると、モジュールは再初期化でき、その状態のために必要となる追加のメモリ量を指定できるということになります。 非負のm_size
は多段階初期化で必要になります。詳細は PEP 3121 を参照。
-
PyMethodDef*
m_methods
¶ PyMethodDef
で定義される、モジュールレベル関数のテーブルへのポインター。関数が存在しない場合は NULL を設定することが可能。
-
PyModuleDef_Slot*
m_slots
¶ 多段階初期化のためのスロット定義の配列で、
{0, NULL}
要素が終端となります。 一段階初期化を使うときは、 m_slots は NULL でなければなりません。
-
traverseproc
m_traverse
¶ A traversal function to call during GC traversal of the module object, or NULL if not needed. This function may be called before module state is allocated (
PyModule_GetState()
may return NULL), and before thePy_mod_exec
function is executed.
-
inquiry
m_clear
¶ A clear function to call during GC clearing of the module object, or NULL if not needed. This function may be called before module state is allocated (
PyModule_GetState()
may return NULL), and before thePy_mod_exec
function is executed.
-
freefunc
m_free
¶ A function to call during deallocation of the module object, or NULL if not needed. This function may be called before module state is allocated (
PyModule_GetState()
may return NULL), and before thePy_mod_exec
function is executed.
-
PyModuleDef_Base
一段階初期化¶
モジュールの初期化関数が直接モジュールオブジェクトを生成して返す場合があります。 これは"一段階初期化"と呼ばれ、次の2つのモジュール生成関数のどちらか1つを使います:
-
PyObject*
PyModule_Create
(PyModuleDef *def)¶ def での定義に従って新しいモジュールオブジェクトを生成します。 これは
PyModule_Create2()
の module_api_version にPYTHON_API_VERSION
を設定したときのように振る舞います。
-
PyObject*
PyModule_Create2
(PyModuleDef *def, int module_api_version)¶ APIバージョンを module_api_version として def での定義に従って新しいモジュールオブジェクトを生成します。 もし指定されたバージョンが実行しているインタープリターのバージョンと異なる場合は、
RuntimeWarning
を発生させます。注釈
ほとんどの場合、この関数ではなく
PyModule_Create()
を利用するべきです。この関数は、この関数の必要性を理解しているときにだけ利用してください。
モジュールオブジェクトが初期化関数から返される前に、たいていは PyModule_AddObject()
などの関数を使ってモジュールオブジェクトにメンバを所属させます。
多段階初期化¶
拡張を直接生成するもう1つのやり方は、"多段階初期化"を要求する方法です。
この方法で作られる拡張モジュールは、よりPythonモジュールに近い振る舞いをします:
初期化処理は、モジュールオブジェクトを生成する 生成段階 とメンバを所属させる 実行段階 に分割されます。
この区別はクラスの __new__()
メソッドと __init__()
メソッドに似ています。
一段階初期化で生成されたモジュールと違い、多段階初期化で生成されたモジュールはシングルトンではありません:
sys.modules のエントリーが削除されモジュールが再インポートされた場合、新しいモジュールオブジェクトが生成され、古いモジュールはPythonモジュールと同じように通常のガベージコレクションで処理されることになります。
デフォルトでは、同じ定義から作られた複数のモジュールは独立であるべきです: あるインスタンスに加えた変更は別のインスタンスに影響しません。
これは、(例えば PyModule_GetState()
を使って取得できる) 全ての状態や、(モジュールの __dict__
や PyType_FromSpec()
で生成された個々のクラスのような) モジュールに所属するものは、特定のモジュールオブジェクト特有のものであるべきということです。
多段階初期化を使って生成される全てのモジュールは サブ・インタプリター をサポートすることが求められます。 複数のモジュールが独立していることを保証するのには、たいていはこのサポートをするだけで十分です。
多段階初期化を要求するために、初期化関数 (PyInit_modulename) は空でない m_slots
を持つ PyModuleDef
を返します。
これを返す前に、 PyModuleDef
インスタンスは次の関数で初期化されなくてはいけません:
-
PyObject*
PyModuleDef_Init
(PyModuleDef *def)¶ モジュール定義が型と参照カウントを正しく報告する、適切に初期化された Python オブジェクトであること保証します。
PyObject*
にキャストされた def を返します。エラーが発生した場合 NULL を返します。バージョン 3.5 で追加.
モジュール定義の m_slots メンバは PyModuleDef_Slot
構造体の配列を指さなければなりません:
-
PyModuleDef_Slot
¶ -
int
slot
¶ スロット ID で、以下で説明されている利用可能な値から選ばれます。
-
void*
value
¶ スロットの値で、意味はスロット ID に依存します。
バージョン 3.5 で追加.
-
int
m_slots 配列はID 0 のスロットで終端されていなければなりません。
利用可能なスロットの型は以下です:
-
Py_mod_create
¶ モジュールオブジェクト自身を生成するために呼ばれる関数を指定します。 このスロットの value ポインタは次のシグネチャを持つ関数を指していなくてはいけません:
-
PyObject*
create_module
(PyObject *spec, PyModuleDef *def)¶
PEP 451 で定義された
ModuleSpec
インスタンスと、モジュール定義を受け取る関数です。 これは新しいモジュールオブジェクトを返すか、エラーを設定して NULL を返すべきです。この関数は最小限に留めておくべきです。 特に任意のPythonコードを呼び出すべきではなく、同じモジュールをインポートしようとすると無限ループに陥るでしょう。
複数の
Py_mod_create
スロットを1つのモジュール定義に設定しない方がよいです。Py_mod_create
が設定されていない場合は、インポート機構はPyModule_New()
を使って通常のモジュールオブジェクトを生成します。 モジュールの名前は定義ではなく spec から取得され、これによって拡張モジュールが動的にモジュール階層における位置を調整できたり、シンボリックリンクを通して同一のモジュール定義を共有しつつ別の名前でインポートできたりします。返されるオブジェクトが
PyModule_Type
のインスタンスである必要はありません。 インポートに関連する属性の設定と取得ができる限りは、どんな型でも使えます。 しかし、PyModuleDef
が NULL でないm_traverse
,m_clear
,m_free
、もしくはゼロでないm_size
、もしくはPy_mod_create
以外のスロットを持つ場合は、PyModule_Type
インスタンスのみが返されるでしょう。-
PyObject*
-
Py_mod_exec
¶ モジュールを 実行する ときに呼ばれる関数を指定します。 これはPythonモジュールのコードを実行するのと同等です: この関数はたいていはクラスと定数をモジュールにします。 この関数のシグネチャは以下です:
複数の
Py_mod_exec
スロットが設定されていた場合は、 m_slots 配列に現れた順に処理されていきます。
多段階初期化についてより詳しくは PEP 489 を見てください。
低水準モジュール作成関数¶
以下の関数は、多段階初期化を使うときに裏側で呼び出されます。
例えばモジュールオブジェクトを動的に生成するときに、これらの関数を直接使えます。
PyModule_FromDefAndSpec
および PyModule_ExecDef
のどちらも、呼び出した後にはモジュールが完全に初期化されていなければなりません。
-
PyObject *
PyModule_FromDefAndSpec
(PyModuleDef *def, PyObject *spec)¶ module と ModuleSpec オブジェクトの spec で定義されたとおりに新しいモジュールオブジェクトを生成します。 この関数は、
PyModule_FromDefAndSpec2()
関数の module_api_version にPYTHON_API_VERSION
を指定した時とおなじようにふるまいます。バージョン 3.5 で追加.
-
PyObject *
PyModule_FromDefAndSpec2
(PyModuleDef *def, PyObject *spec, int module_api_version)¶ APIバージョンを module_api_version として、 module と ModuleSpec オブジェクトの spec で定義されたとおりに新しいモジュールオブジェクトを生成します。 もし指定されたバージョンが実行しているインタープリターのバージョンと異なる場合は、
RuntimeWarning
を発生させます。注釈
ほとんどの場合、この関数ではなく
PyModule_FromDefAndSpec()
を利用するべきです。 この関数は、この関数の必要性を理解しているときにだけ利用してください。バージョン 3.5 で追加.
-
int
PyModule_ExecDef
(PyObject *module, PyModuleDef *def)¶ def で与えられた任意の実行スロット (
Py_mod_exec
) を実行します。バージョン 3.5 で追加.
-
int
PyModule_SetDocString
(PyObject *module, const char *docstring)¶ module の docstring を docstring に設定します。 この関数は、
PyModuleDef
からPyModule_Create
もしくはPyModule_FromDefAndSpec
を使ってモジュールを生成するときに自動的に呼び出されます。バージョン 3.5 で追加.
-
int
PyModule_AddFunctions
(PyObject *module, PyMethodDef *functions)¶ 終端が NULL になっている functions 配列にある関数を module に追加します。
PyMethodDef
構造体の個々のエントリについては PyMethodDef の説明を参照してください (モジュールの名前空間が共有されていないので、 C で実装されたモジュールレベル "関数" はたいていモジュールを1つ目の引数として受け取り、 Python クラスのインスタンスメソッドに似た形にします)。 この関数は、PyModuleDef
からPyModule_Create
もしくはPyModule_FromDefAndSpec
を使ってモジュールを生成するときに自動的に呼び出されます。バージョン 3.5 で追加.
サポート関数¶
モジュールの初期化関数 (一段階初期化を使う場合) 、あるいはモジュールの実行スロットから呼び出される関数 (多段階初期化を使う場合) は次の関数を使うと、モジュールの state の初期化を簡単にできます:
-
int
PyModule_AddObject
(PyObject *module, const char *name, PyObject *value)¶ module にオブジェクトを name として追加します。 この関数はモジュールの初期化関数から利用される便利関数です。 これは value への参照を盗みます。 エラーのときには
-1
を、成功したときには0
を返します。
-
int
PyModule_AddIntConstant
(PyObject *module, const char *name, long value)¶ module に整数定数を name として追加します。この便宜関数はモジュールの初期化関数から利用されています。エラーのときには
-1
を、成功したときには0
を返します。
-
int
PyModule_AddStringConstant
(PyObject *module, const char *name, const char *value)¶ module に文字列定数を name として追加します。 この便利関数はモジュールの初期化関数から利用されています。 文字列 value は NULL 終端されていなければなりません。 エラーのときには
-1
を、成功したときには0
を返します。
モジュール検索¶
一段階初期化は、現在のインタプリタのコンテキストから探せるシングルトンのモジュールを生成します。 これによって、後からモジュール定義への参照だけでモジュールオブジェクトが取得できます。
多段階初期化を使うと単一の定義から複数のモジュールが作成できるので、これらの関数は多段階初期化を使って作成されたモジュールには使えません。
-
PyObject*
PyState_FindModule
(PyModuleDef *def)¶ 現在のインタプリタの def から作られたモジュールオブジェクトを返します。このメソッドの前提条件として、前もって
PyState_AddModule()
でインタプリタの state にモジュールオブジェクトを連結しておくことを要求します。対応するモジュールオブジェクトが見付からない、もしくは事前にインタプリタの state に連結されていない場合は、 NULL を返します。
-
int
PyState_AddModule
(PyObject *module, PyModuleDef *def)¶ 関数に渡されたモジュールオブジェクトを、インタプリタの state に連結します。この関数を使うことで
PyState_FindModule()
からモジュールオブジェクトにアクセスできるようになります。一段階初期化を使って作成されたモジュールにのみ有効です。
バージョン 3.3 で追加.
-
int
PyState_RemoveModule
(PyModuleDef *def)¶ def から作られたモジュールオブジェクトをインタプリタ state から削除します。
バージョン 3.3 で追加.