私はPythonプログラムが既存のC++ライブラリを呼び出すことができるようにインタフェースを開発しています。私が正しく理解していれば、そのようなインターフェイス(とC++ライブラリ)は、モジュールとして、例えばabc
のようにインポートする必要があります。インタフェース内の型がインターフェイスのC++側の静的変数として定義され、以下の配列を使ってPythonに登録されている:Python拡張で型を定義するときに、tp_nameフィールドに何を入れるべきですか?
void PythonRegistrationData::RegisterType(PyObject* module, PyTypeObject* type)
{
if (type->ob_refcnt < 2)
{
if (type->tp_base != NULL)
RegisterType(module, type->tp_base);
Py_INCREF(type);
if (PyType_Ready(type) != 0)
throw GPython::DummyError();
PyModule_AddObject(module, type->tp_name, as<PyObject>(type));
}
}
(再帰は、その基底クラスは、派生クラス前に登録されることを保証することです。モジュールは以前に作成されています)。C-API docsによると、“静的に割り当てられた型オブジェクトの場合、tp_nameフィールドにはドットが含まれている必要があります。 ”;このため、tp_name
を"abc.MyType"
に初期化します。これを行うと、モジュールを読み込んだ後、タイプを使用しようとすると'module' object has no attribute 'MyType'
となります(前にimport abc
を実行したx = abc.MyType()
)。 "MyType"
だけを使用すると動作するようですが、これは公式のドキュメントとチュートリアルの例の両方に矛盾するようです。
したがって、tp_name
フィールドの正確な意味は何ですか。実際にはどうしたらよいでしょうか?それにモジュール名を入れないのはどういう意味ですか?あなたは属性名として「abc.MyType」を使用して(属性を設定することを意味)モジュールにタイプを追加している
PyModule_AddObject(module, type->tp_name, as<PyObject>(type));
を行うことにより
私は理解できません。私は 'getattr'のような関数を使って型にアクセスすることには興味がありません。モジュールのメンバである型として機能する型が必要です。 'abc.MyType()'のような式で(型の新しいインスタンスを作成するため)。私が修飾子( '' abc.MyType "'を 'tp_name'で使用すると)、私はそうしようとするとエラーメッセージが出ます。 –
私は既に持っているものとは違った方法で質問に答える方法がわかりません。あなたの問題は 'tp_name'ではない、あなたの問題は' PyModule_AddObject'に渡す文字列です。あなたは '' abc.MyType "'を 'PyModule_AddObject'に渡しています。代わりに '' MyType ''を渡す必要があります。 'PyModule_AddObject'に直接' tp_name'を渡すべきではありません。 –
それはキーのように聞こえます:私は 'PyModule_AddObject'の名前としてこの文字列を正確に渡していたということを見落としてしまいました。 –