2017-09-09 45 views
1

我想知道如何從C++ for Python中定義靜態類變量?等效Python代碼會是這樣:如何用C++在Python中定義靜態類屬性?

class foo: 
    bar = int 

我試圖用定義類型時tp_getset場,但事實證明這是行不通的,並返回Python中的getset_descriptor,並要求當它不工作(AttributeError)。此外,Python文檔說直接操縱tp_dict與C API是不安全的。但它沒有告訴用什麼來代替。 (請參閱 here

我在示例中故意選擇了int,因爲我引用了其他一些類,如果這很重要的話。

+1

也許在這裏你可以找到答案https://stackoverflow.com/questions/68645/static-class-variables-in-python – magicleon

+0

@magicleon,是的,這就是我想要的。但我的意思是來自C++,使用C-API的庫/模塊。 – YiFei

+0

請參閱[issue#12719](https://bugs.python.org/issue12719)瞭解爲什麼訪問'tp_dict'是不安全的。 – myaut

回答

0

tp_getset定義爲descriptors爲一種類型;描述符在通過__getattribute__鉤子訪問時綁定到實例,所以不適合定義類屬性。

您可以通過在類別PyTypeObject.tp_dict object上設置屬性來爲類添加屬性;在模塊的初始化功能(PyInit_<modulename>)這樣做,例如,在完成最終用PyType_Ready()類型(這確保了tp_dict對象存在)後:

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 module,其中設置了datetime.min,datetime.max等類別屬性。

+0

我可以說在我調用'PyModule_AddObject'之前直接修改'tp_dict'是安全的嗎? – YiFei

+0

@YiFei:我相信,有一種與'PyObject_SetAttrString()'的交互不受支持,但是在模塊初始化程序中修改'tp_dict'會在Python代碼庫的多個地方使用。 –

+0

@YiFei:例如,'sys'模塊*從特定類型的'tp_dict'對象中刪除*條目(除去'__new__'方法來阻止新的實例)。 –