2017-09-09 11 views
1

私はPythonのC++から静的なクラス変数をどのように定義できますか?同等のPythonのコードは次のようになります:C++からPythonで静的クラス属性を定義する方法は?

class foo: 
    bar = int 

私はタイプを定義するときtp_getsetフィールドを使用しようとしましたが、呼び出されたとき、それは動作しませんが判明し、Pythonでgetset_descriptorを返し、それは動作しません。インスタンス(AttributeError)。さらに、Pythonのdocは、C APIを使って直接tp_dictを操作することは安全ではないと述べています。しかし、代わりに何を使うべきかは分かりません。 ( hereを参照してください)

この例では、意図的にintを選択しました。これは、他のクラスを参照しています。

+1

おそらくここで答えを見つけることができますhttps://stackoverflow.com/questions/68645/static-class-variables-in-python – magicleon

+0

@magicleon、はい、それは私がしたいです。しかし、私はC++から、C-APIを使ったライブラリ/モジュールを意味していました。 – YiFei

+0

'tp_dict'にアクセスするのがなぜ安全でないのかについては、[issue#12719](https://bugs.python.org/issue12719)を参照してください。 – myaut

答えて

0

tp_getsetは、タイプとしてdescriptorsを定義します。記述子は__getattribute__フックでアクセスするとインスタンスにバインドされるため、クラス属性の定義には適していません。

クラスに属性を追加するには、型のPyTypeObject.tp_dict objectに属性を設定します。 (tp_dictオブジェクトが存在を確認します)PyType_Ready()有するタイプ確定した後、例えば、モジュールの初期化関数(PyInit_<modulename>)でこれを行う:

PyObject *d; 
PyObject *bar; 

d = PyFoo_Type.tp_dict; 

bar = PyLong_FromLong(42); 
if (bar == NULL || PyDict_SetItemString(d, "bar", bar) < 0) 
    return NULL; 
Py_DECREF(bar); 

これはテストされていないCコードであると、私は自信を持ってC++バージョンをあなたに提供するために、C++に慣れていません。

実際の例を表示する場合は、datetime.mindatetime.maxなどのクラス属性が設定されているdatetime moduleを参照してください。

+0

'PyModule_AddObject'を呼び出す前に' tp_dict'を直接変更するのは安全だと言えますか? – YiFei

+0

@YiFei:私はそう信じています。サポートされていない 'PyObject_SetAttrString()'との対話がありますが、モジュールの初期化子で 'tp_dict'を変更することは、Pythonコードベースの複数の場所で使用されます。 –

+0

@YiFei:例えば、 'sys'モジュールは、特定の型の' tp_dict'オブジェクトからエントリを削除します(新しいインスタンスを防ぐために '__new__'メソッドを削除します)。 –

関連する問題