Reputation: 582
How would I add a static, typed member to a cython class? The syntax for adding typed instance-members uses the syntax as follows (e.g.):
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
Upvotes: 7
Views: 5322
Reputation: 511
Another workaround (with a nested class, which is a specific kind of class attribute):
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']
Which seems to work (the exception is expected):
>>> 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'>
I'm using a nested class here, but it could be anything.
It's not 100% clean:
<class 'mymodule.Test1.Test2'>
as a result to my last query (could be fixed, but do we want more tricks?)Upvotes: 0
Reputation: 30889
Just because you can do it in C really doesn't mean you can do it in Cython.
A workround might involve using global variables, and class properties so you can access them through class instances. I'm not sure if it's really better than using global variables though
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
You'd have to measure how much speed you lost through that method (and maybe consider making __get__
and __set__
cpdef
if you can - I'm not sure). The only thing that doesn't let you do that a genuine static variable does is to access it as MyClass.static_variable
.
Upvotes: 6