如何将静态成员添加到 Cython class(来自 python,不是 C)

How to add a static member to a Cython class (from python, not C)

如何向 cython class 添加静态 typed 成员?添加类型化 instance-members 的语法使用如下语法(例如):

import cython

cdef class NoStaticMembers:

   cdef public int instanceValue # but, how do I create a static member??

   def __init__(self, int value):
       self.instanceValue = value

仅仅因为您可以在 C 中完成并不意味着您可以在 Cython 中完成。

解决方法可能涉及使用全局变量和 class 属性,以便您可以通过 class 实例访问它们。我不确定它是否真的比使用全局变量更好

import cython

cdef int MyClass_static_variable

cdef class MyClass:
   property static_variable:
      def __get__(self):
         return MyClass_static_variable

      def __set__(self, x):
         global MyClass_static_variable
         MyClass_static_variable = x

您必须测量通过该方法损失了多少速度(如果可以的话,也许可以考虑制作 __get____set__ cpdef - 我不确定) .唯一不能让你做的是真正的静态变量做的是访问它作为 MyClass.static_variable.

另一种解决方法(带有嵌套 class,这是一种特定的 class 属性):

from cpython.object cimport PyTypeObject, PyObject
from cpython.dict cimport PyDict_SetItem

cdef class Test1:
    pass

cdef class Test2:
    pass

# Building something close to:
#
# class Test1:
#     class Test2:
#         pass

PyDict_SetItem(<object>(<PyTypeObject*>Test1).tp_dict, 'Test2', Test2)
del globals()['Test2'] 

这似乎有效(预期会出现异常):

>>> import mymodule
>>> mymodule.Test1
<class 'mymodule.Test1'>
>>> mymodule.Test2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'mymodule' has no attribute 'Test2'
>>> mymodule.Test1.Test2
<class 'mymodule.Test2'>

我在这里使用嵌套 class,但它可以是任何东西。

它不是 100% 干净的:

  • 我本以为 <class 'mymodule.Test1.Test2'> 是我上次查询的结果(可以修复,但我们需要更多技巧吗?)
  • 在 PyType_Ready 之后修改 tp_dict 不干净(是吗?)。但是,在我们的具体用例中,我认为这并不重要。