モジュールオブジェクト—Pythonドキュメント

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

モジュールオブジェクト

PyTypeObject PyModule_Type
PyTypeObject のこのインスタンスは、Pythonモジュールタイプを表します。 これは、types.ModuleTypeとしてPythonプログラムに公開されています。
int PyModule_Check(PyObject *p)
p がモジュールオブジェクト、またはモジュールオブジェクトのサブタイプである場合はtrueを返します。 この関数は常に成功します。
int PyModule_CheckExact(PyObject *p)
p がモジュールオブジェクトであるが、 PyModule_Type のサブタイプではない場合、trueを返します。 この関数は常に成功します。
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)
PyModule_NewObject()に似ていますが、名前はUnicodeオブジェクトではなくUTF-8でエンコードされた文字列です。
PyObject *PyModule_GetDict(PyObject *module)

module の名前空間を実装するディクショナリオブジェクトを返します。 このオブジェクトは、モジュールオブジェクトの __ dict __ 属性と同じです。 module がモジュールオブジェクト(またはモジュールオブジェクトのサブタイプ)でない場合、 SystemError が発生し、NULLが返されます。

拡張機能は、モジュールの __ dict __ を直接操作するのではなく、他の PyModule _ * および PyObject _ * 関数を使用することをお勧めします。

PyObject *PyModule_GetNameObject(PyObject *module)

モジュール__ name __ 値を返します。 モジュールが提供しない場合、または文字列でない場合は、 SystemError が発生し、NULLが返されます。

バージョン3.3の新機能。

const char *PyModule_GetName(PyObject *module)
PyModule_GetNameObject()に似ていますが、エンコードされた名前を'utf-8'に返します。
void *PyModule_GetState(PyObject *module)
モジュールの「状態」、つまりモジュール作成時に割り当てられたメモリブロックへのポインタ、または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の新機能。

const char *PyModule_GetFilename(PyObject *module)

PyModule_GetFilenameObject()に似ていますが、エンコードされたファイル名を「utf-8」に返します。

バージョン3.2以降非推奨: PyModule_GetFilename()は、エンコードできないファイル名でUnicodeEncodeErrorを発生させます。代わりに、 PyModule_GetFilenameObject()を使用してください。

Cモジュールの初期化

モジュールオブジェクトは通常、拡張モジュール(初期化関数をエクスポートする共有ライブラリ)またはコンパイル済みモジュール(初期化関数が PyImport_AppendInittab()を使用して追加される)から作成されます。 詳細については、 CおよびC ++拡張機能の構築または組み込みPythonの拡張を参照してください。

初期化関数は、モジュール定義インスタンスを PyModule_Create()に渡して、結果のモジュールオブジェクトを返すか、定義構造体自体を返すことで「マルチフェーズ初期化」を要求できます。

type PyModuleDef

モジュール定義構造体。モジュールオブジェクトの作成に必要なすべての情報を保持します。 通常、モジュールごとに、このタイプの静的に初期化された変数は1つだけです。

PyModuleDef_Base m_base

このメンバーは常にPyModuleDef_HEAD_INITに初期化してください。

const char *m_name

新しいモジュールの名前。

const char *m_doc

モジュールのDocstring。 通常、 PyDoc_STRVAR で作成されたdocstring変数が使用されます。

Py_ssize_t m_size

モジュールの状態は、静的グローバルではなく、 PyModule_GetState()で取得できるモジュールごとのメモリ領域に保持される場合があります。 これにより、モジュールは複数のサブインタープリターで安全に使用できるようになります。

このメモリ領域は、モジュール作成時に m_size に基づいて割り当てられ、 m_free 関数が呼び出された後、モジュールオブジェクトの割り当てが解除されると解放されます(存在する場合)。

m_size-1に設定すると、モジュールはグローバル状態であるため、サブインタープリターをサポートしません。

負でない値に設定すると、モジュールを再初期化でき、その状態に必要な追加のメモリ量を指定できます。 マルチフェーズの初期化には、負でないm_sizeが必要です。

詳細については、 PEP 3121 を参照してください。

PyMethodDef *m_methods

PyMethodDef 値で記述されるモジュールレベルの関数のテーブルへのポインター。 関数が存在しない場合は、NULLにすることができます。

PyModuleDef_Slot *m_slots

{0, NULL}エントリで終了する、マルチフェーズ初期化用のスロット定義の配列。 単相初期化を使用する場合、 m_slotsNULLである必要があります。

バージョン3.5で変更:バージョン3.5より前は、このメンバーは常にNULLに設定され、次のように定義されていました。

inquiry m_reload


traverseproc m_traverse

モジュールオブジェクトのGCトラバーサル中に呼び出すトラバーサル関数。不要な場合はNULL

モジュール状態が要求されたがまだ割り当てられていない場合、この関数は呼び出されません。 これは、モジュールが作成された直後で、モジュールが実行される前の場合です( Py_mod_exec 関数)。 より正確には、 m_size が0より大きく、モジュールの状態( PyModule_GetState()によって返される)がNULLの場合、この関数は呼び出されません。

バージョン3.9で変更:モジュールの状態が割り当てられる前に呼び出されなくなりました。

inquiry m_clear

モジュールオブジェクトのGCクリア中に呼び出すclear関数、または不要な場合はNULL

モジュール状態が要求されたがまだ割り当てられていない場合、この関数は呼び出されません。 これは、モジュールが作成された直後で、モジュールが実行される前の場合です( Py_mod_exec 関数)。 より正確には、 m_size が0より大きく、モジュールの状態( PyModule_GetState()によって返される)がNULLの場合、この関数は呼び出されません。

PyTypeObject.tp_clear と同様に、この関数は、モジュールの割り当てが解除される前に常に呼び出されるわけではありません。 たとえば、参照カウントでオブジェクトが使用されなくなったと判断できる場合、サイクリックガベージコレクタは関与せず、 m_free が直接呼び出されます。

バージョン3.9で変更:モジュールの状態が割り当てられる前に呼び出されなくなりました。

freefunc m_free

モジュールオブジェクトの割り当て解除中に呼び出す関数、または不要な場合はNULL

モジュール状態が要求されたがまだ割り当てられていない場合、この関数は呼び出されません。 これは、モジュールが作成された直後で、モジュールが実行される前の場合です( Py_mod_exec 関数)。 より正確には、 m_size が0より大きく、モジュールの状態( PyModule_GetState()によって返される)がNULLの場合、この関数は呼び出されません。

バージョン3.9で変更:モジュールの状態が割り当てられる前に呼び出されなくなりました。

単相初期化

モジュール初期化関数は、モジュールオブジェクトを直接作成して返す場合があります。 これは「単相初期化」と呼ばれ、次の2つのモジュール作成関数のいずれかを使用します。

PyObject *PyModule_Create(PyModuleDef *def)
def の定義を指定して、新しいモジュールオブジェクトを作成します。 これは、 module_api_versionPYTHON_API_VERSIONに設定された PyModule_Create2()のように動作します。
PyObject *PyModule_Create2(PyModuleDef *def, int module_api_version)

APIバージョン module_api_version を想定して、 def の定義を指定して、新しいモジュールオブジェクトを作成します。 そのバージョンが実行中のインタープリターのバージョンと一致しない場合、 RuntimeWarning が発行されます。

ノート

この関数のほとんどの使用法は、代わりに PyModule_Create()を使用する必要があります。 必要であると確信できる場合にのみ、これを使用してください。

初期化関数で返される前に、結果のモジュールオブジェクトは通常、 PyModule_AddObject()などの関数を使用して入力されます。


多相初期化

拡張機能を指定する別の方法は、「マルチフェーズ初期化」を要求することです。 この方法で作成された拡張モジュールは、Pythonモジュールのように動作します。初期化は、モジュールオブジェクトが作成されるときの作成フェーズと、データが入力されるときの実行フェーズに分割されます。 この違いは、クラスの__new__()メソッドと__init__()メソッドに似ています。

単相初期化を使用して作成されたモジュールとは異なり、これらのモジュールはシングルトンではありません。 sys.modules エントリが削除され、モジュールが再インポートされると、新しいモジュールオブジェクトが作成され、古いモジュールが対象になります。 Pythonモジュールと同様に、通常のガベージコレクションに。 デフォルトでは、同じ定義から作成された複数のモジュールは独立している必要があります。1つを変更しても、他のモジュールには影響しません。 これは、すべての状態がモジュールオブジェクトに固有である必要があることを意味します(たとえば、 PyModule_GetState())、またはそのコンテンツ(モジュールの__dict__または PyType_FromSpec()で作成された個々のクラスなど)を使用します。

マルチフェーズ初期化を使用して作成されたすべてのモジュールは、サブインタープリターをサポートすることが期待されています。 通常、これを実現するには、複数のモジュールが独立していることを確認するだけで十分です。

マルチフェーズ初期化を要求するために、初期化関数(PyInit_modulename)は、空でない m_slots を持つ PyModuleDef インスタンスを返します。 返される前に、PyModuleDefインスタンスを次の関数で初期化する必要があります。

PyObject *PyModuleDef_Init(PyModuleDef *def)

モジュール定義が適切に初期化されたPythonオブジェクトであり、そのタイプと参照カウントを正しく報告することを保証します。

defPyObject*にキャストするか、エラーが発生した場合はNULLを返します。

バージョン3.5の新機能。

モジュール定義の m_slots メンバーは、PyModuleDef_Slot構造体の配列を指している必要があります。

type PyModuleDef_Slot
int slot

以下で説明する使用可能な値から選択されたスロットID。

void *value

スロットの値。その意味はスロットIDによって異なります。

バージョン3.5の新機能。

m_slots 配列は、ID0のスロットで終了する必要があります。

使用可能なスロットタイプは次のとおりです。

Py_mod_create

モジュールオブジェクト自体を作成するために呼び出される関数を指定します。 このスロットの value ポインターは、署名の関数を指している必要があります。

PyObject *create_module(PyObject *spec, PyModuleDef *def)

この関数は、 PEP 451 で定義されている ModuleSpec インスタンスとモジュール定義を受け取ります。 新しいモジュールオブジェクトを返すか、エラーを設定してNULLを返す必要があります。

この機能は最小限に抑える必要があります。 特に、同じモジュールを再度インポートしようとすると無限ループが発生する可能性があるため、任意のPythonコードを呼び出さないでください。

1つのモジュール定義で複数のPy_mod_createスロットを指定することはできません。

Py_mod_createが指定されていない場合、インポート機構は PyModule_New()を使用して通常のモジュールオブジェクトを作成します。 名前は定義ではなく spec から取得され、拡張モジュールがモジュール階層内の位置に動的に調整され、シンボリックリンクを介して異なる名前でインポートされ、すべて単一のモジュール定義を共有できるようにします。

返されるオブジェクトが PyModule_Type のインスタンスである必要はありません。 インポート関連の属性の設定と取得をサポートしている限り、どのタイプでも使用できます。 ただし、PyModuleDefNULL m_traversem_clearm_free以外のインスタンスがある場合は、PyModule_Typeインスタンスのみが返されます。 ; ゼロ以外m_size; またはPy_mod_create以外のスロット。

Py_mod_exec

モジュールを実行するために呼び出される関数を指定します。 これは、Pythonモジュールのコードを実行するのと同じです。通常、この関数はクラスと定数をモジュールに追加します。 関数のシグネチャは次のとおりです。

int exec_module(PyObject *module)

複数のPy_mod_execスロットが指定されている場合、それらは m_slots 配列に表示される順序で処理されます。

マルチフェーズ初期化の詳細については、 PEP 489 を参照してください。


低レベルのモジュール作成関数

マルチフェーズ初期化を使用する場合、内部で次の関数が呼び出されます。 モジュールオブジェクトを動的に作成する場合など、直接使用できます。 モジュールを完全に初期化するには、PyModule_FromDefAndSpecPyModule_ExecDefの両方を呼び出す必要があることに注意してください。

PyObject *PyModule_FromDefAndSpec(PyModuleDef *def, PyObject *spec)

module およびModuleSpec spec の定義を指定して、新しいモジュールオブジェクトを作成します。 これは、 module_api_versionPYTHON_API_VERSIONに設定された PyModule_FromDefAndSpec2()のように動作します。

バージョン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 に設定します。 この関数は、PyModule_CreateまたはPyModule_FromDefAndSpecのいずれかを使用して、PyModuleDefからモジュールを作成するときに自動的に呼び出されます。

バージョン3.5の新機能。

int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions)

NULLで終了した関数配列からモジュールに関数を追加します。 個々のエントリの詳細については、 PyMethodDef のドキュメントを参照してください(共有モジュール名前空間がないため、Cで実装されたモジュールレベルの「関数」は通常、最初のパラメーターとしてモジュールを受け取り、インスタンスメソッドと同様になりますPythonクラス)。 この関数は、PyModule_CreateまたはPyModule_FromDefAndSpecのいずれかを使用して、PyModuleDefからモジュールを作成するときに自動的に呼び出されます。

バージョン3.5の新機能。


サポート機能

モジュール初期化関数(単相初期化を使用する場合)またはモジュール実行スロットから呼び出される関数(多相初期化を使用する場合)は、次の関数を使用してモジュール状態の初期化に役立てることができます。

int PyModule_AddObject(PyObject *module, const char *name, PyObject *value)

オブジェクトをモジュール名前として追加します。 これは、モジュールの初期化関数から使用できる便利な関数です。 これにより、成功すると value への参照が盗まれます。 エラーの場合は-1を返し、成功の場合は0を返します。

ノート

参照を盗む他の関数とは異なり、PyModule_AddObject()は、成功時に の参照カウントをデクリメントするだけです。

これは、戻り値をチェックする必要があり、呼び出しコードはエラー時に手動で Py_DECREF() value する必要があることを意味します。 使用例:

Py_INCREF(spam);
if (PyModule_AddObject(module, "spam", spam) < 0) {
    Py_DECREF(module);
    Py_DECREF(spam);
    return NULL;
}
int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
モジュール名前として整数定数を追加します。 この便利な関数は、モジュールの初期化関数から使用できます。 エラーの場合は-1を返し、成功の場合は0を返します。
int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value)
文字列定数を modulename として追加します。 この便利な関数は、モジュールの初期化関数から使用できます。 文字列 valueNULLで終了する必要があります。 エラーの場合は-1を返し、成功の場合は0を返します。
int PyModule_AddIntMacro(PyObject *module, macro)
モジュールにint定数を追加します。 名前と値はマクロから取得されます。 たとえば、PyModule_AddIntMacro(module, AF_INET)は、 AF_INET の値を持つint定数 AF_INETモジュールに追加します。 エラーの場合は-1を返し、成功の場合は0を返します。
int PyModule_AddStringMacro(PyObject *module, macro)
モジュールに文字列定数を追加します。
int PyModule_AddType(PyObject *module, PyTypeObject *type)

タイプオブジェクトをモジュールに追加します。 型オブジェクトは、内部で PyType_Ready()を呼び出すことによって完成されます。 タイプオブジェクトの名前は、ドットの後の tp_name の最後のコンポーネントから取得されます。 エラーの場合は-1を返し、成功の場合は0を返します。

バージョン3.9の新機能。


モジュールルックアップ

単相初期化は、現在のインタプリタのコンテキストで検索できるシングルトンモジュールを作成します。 これにより、モジュール定義への参照のみを使用して、モジュールオブジェクトを後で取得できます。

これらの関数は、マルチフェーズ初期化を使用して作成されたモジュールでは機能しません。これは、そのようなモジュールが1つの定義から複数作成される可能性があるためです。

PyObject *PyState_FindModule(PyModuleDef *def)
現在のインタプリタ用に def から作成されたモジュールオブジェクトを返します。 このメソッドでは、モジュールオブジェクトが PyState_AddModule()を使用してインタプリタ状態に事前にアタッチされている必要があります。 対応するモジュールオブジェクトが見つからないか、インタプリタ状態にまだアタッチされていない場合は、NULLを返します。
int PyState_AddModule(PyObject *module, PyModuleDef *def)

関数に渡されたモジュールオブジェクトをインタープリター状態にアタッチします。 これにより、モジュールオブジェクトに PyState_FindModule()を介してアクセスできるようになります。

単相初期化を使用して作成されたモジュールでのみ有効です。

Pythonは、モジュールのインポート後にPyState_AddModuleを自動的に呼び出すため、モジュール初期化コードから呼び出す必要はありません(ただし無害です)。 明示的な呼び出しは、モジュール自体の初期化コードがその後PyState_FindModuleを呼び出す場合にのみ必要です。 この関数は主に、代替のインポートメカニズムを実装することを目的としています(直接呼び出すか、必要な状態の更新の詳細について実装を参照することによって)。

発信者はGILを保持する必要があります。

成功した場合は0を返し、失敗した場合は-1を返します。

バージョン3.3の新機能。

int PyState_RemoveModule(PyModuleDef *def)

def から作成されたモジュールオブジェクトをインタープリター状態から削除します。 成功した場合は0を返し、失敗した場合は-1を返します。

発信者はGILを保持する必要があります。

バージョン3.3の新機能。