Cython子类能否访问父类C-only属性?如何兼顾快速实例化?
Cython扩展类型属性访问与实例化问题解答
1. 是否存在子类可访问的C-only父类属性?
有。使用cdef protected修饰父类属性,这类属性仅允许当前类及子类的C级代码(cdef/cfunc函数)访问,不会暴露到Python层,完全保留C级访问性能。
示例代码:
import cython @cython.cclass cdef class Base: # protected修饰的C-only属性,子类C级可访问 cdef protected int _base_attr cdef void _init_base(self, int value): self._base_attr = value @cython.cclass cdef class Derived(Base): cdef void _init_derived(self, int value): # 子类C级代码直接访问父类protected属性 self._base_attr = value # 或调用父类的C级初始化方法 self._init_base(value)
2. 是否存在其他实例的C代码可访问的C-only类属性?
可以,分两种场景处理:
- 同一模块内:直接在
cdef class中定义cdef属性,同一模块内其他类的cdef/cfunc代码只要持有目标实例的C级引用(如cdef Base b = instance),即可直接访问该属性,全程C级速度。 - 跨模块:将目标类声明为
cdef api class,属性用cdef修饰,其他模块通过cimport导入该类后,即可在C级代码中访问实例属性。
同一模块示例:
import cython @cython.cclass cdef class Base: cdef int instance_attr # 同一模块内C级代码可访问 @cython.cclass cdef class AnotherClass: cdef void modify_base(self, Base b): b.instance_attr = 100 # C级直接赋值
跨模块示例(base.pyx):
cdef api class Base: cdef int instance_attr
跨模块示例(other.pyx):
cimport base cdef class AnotherClass: cdef void modify_base(self, base.Base b): b.instance_attr = 100
3. 能否兼顾快速实例化与C级属性访问?
完全可以。核心思路是:用__new__快速创建实例(跳过Python层__init__的开销),再通过C级初始化方法(cdef修饰的方法)完成属性赋值,避免Python层的属性访问逻辑。
示例代码:
import cython @cython.cclass cdef class Base: cdef protected int _value # C级初始化方法,直接操作属性 cdef void _init(self, int value): self._value = value @cython.cclass cdef class Derived(Base): cdef protected int _derived_val cdef void _init(self, int base_val, int derived_val): # 调用父类的C级初始化 self.Base._init(self, base_val) self._derived_val = derived_val # 快速实例化+ C级初始化的cfunc @cython.cfunc cdef Derived create_derived(int base_val, int derived_val): # 用__new__快速创建实例,无Python层开销 cdef Derived d = Derived.__new__(Derived) # 调用C级初始化方法,直接赋值属性 d._init(base_val, derived_val) return d
内容的提问来源于stack exchange,提问作者JuanT
相关产品推荐
相关产品推荐

