在cdef类中混合使用cdef和常规python属性

2024-10-03 23:29:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习Cython,现在正在尝试它。我尝试了基本的cdef类示例程序,它工作得很好。在

现在我要做的是在cdef类类型中混合使用cdef和非cdef属性,如下所示

cdef class Context:
    cdef public int byteIndex, bitIndex

    def __init__(self, msg = "", msg_len = 0):
        self.msg = msg 
        self.msg_len = msg_len 
        self.byteIndex = 0
        self.bitIndex = 7

但一旦我实例化了对象,我就得到了错误

!! AttributeError: 'c_asnbase.Context' object has no attribute 'msg'

这是否意味着一旦定义了一个带有cdef的python类,所有self.*属性都必须是cdef定义的?在


Tags: self程序示例类型len属性定义context
2条回答

正如@DavidW所指出的,cdef类的问题是它们没有__dict__。如果确实需要,可以将__dict__添加到类定义中:

%%cython
cdef class A:
    cdef dict __dict__        # now the usual attribute look-up is possible
    cdef readonly int answer 
    def __init__(self):
        self.answer=42             #cdef attribute
        self.question="unknown"    #pure python attribute, possible

现在:

^{pr2}$

注意:如果cdef class A没有__dict__,而是用cdef public object question来定义,则setattr(a,'new_attr', None)是不可能的。在

显然,使用__dict__会有额外的成本,因此当性能重要时,可能会使用预定义的属性。在

另一种方法是创建cdef class的子类并使用它而不是基类。在


注意:here is the part在关于动态属性的Cython文档中。在

Does this mean once you define a python class with cdef all self.* attributes have to be cdef defined?

是的。这在the documentation中有明确的表述:

Attributes in cdef classes behave differently from attributes in regular classes:

  • All attributes must be pre-declared at compile-time
  • ...

通过将属性定义为object类型,可以很好地存储字符串:

cdef public object msg

在内部,这是因为cdef class没有字典,这样可以节省空间并加快属性访问速度,但这确实意味着它不能在运行时添加任意属性。这相当类似于在普通Python类中使用__slots__。在

相关问题 更多 >