2017-09-09 44 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__'方法来阻止新的实例)。 –