Skip to content

扩展类型与类

本章讲解Cython扩展类型的定义和优化。cdef class是Cython的高性能类定义方式,比Python类快10-100倍。

学习路径:类定义 → 属性优化 → 继承限制 → 结构体嵌入 → 描述符

核心概念:

  • cdef class:扩展类型,C级属性访问
  • cpdef:双重可调用方法
  • cdef struct:嵌入C结构体

功能说明:使用cdef声明C级属性,绕过Python字典查找。

# Cython扩展类型
cdef class Point:
cdef double x
cdef double y
def __init__(self, double x, double y):
self.x = x
self.y = y
cpdef double distance(self):
return (self.x ** 2 + self.y ** 2) ** 0.5

输出示例:

>>> p = Point(3.0, 4.0)
>>> p.distance()
5.0

功能说明:三种方法类型:cdef(最快)、cpdef(双重调用)、def(仅Python)。

cdef class Circle:
cdef double _x
cdef double _y
cdef double _radius
def __init__(self, double x, double y, double radius):
self._x = x
self._y = y
self._radius = radius
# C级方法 - 最快,但Python不可直接调用
cdef double area(self):
return 3.14159 * self._radius ** 2
# Python可调用方法
cpdef double circumference(self):
return 2.0 * 3.14159 * self._radius
# 属性定义
property x:
def __get__(self):
return self._x
def __set__(self, value):
self._x = value

性能对比(1000万次调用):

方法类型耗时
cdef~50ms
cpdef~150ms
def~800ms

功能说明:使用__cinit__和__dealloc__管理资源。

cdef class Resource:
cdef void* _handle
cdef bint _valid
def __cinit__(self, str name):
self._handle = open_resource(name)
if self._handle == NULL:
raise MemoryError("Failed to open resource")
self._valid = True
def __dealloc__(self):
if self._valid and self._handle != NULL:
close_resource(self._handle)
self._valid = False

功能说明:cpdef方法可在Python和Cython中调用。

cdef class Optimized:
cdef int _value
cdef list _cache
def __init__(self, int value):
self._value = value
self._cache = []
# cpdef方法 - C和Python都可调用
cpdef int get_value(self):
return self._value
cpdef void set_value(self, int value):
self._value = value

功能说明:延迟计算直到真正需要结果。

cdef class LazyClass:
cdef int _expensive_result
cdef bint _computed
cdef list _data
def __init__(self, list data):
self._data = data
self._computed = False
cdef int _ensure_computed(self):
if not self._computed:
self._expensive_result = sum(self._data)
self._computed = True
return self._expensive_result
cpdef int get_result(self):
return self._ensure_computed()

功能说明:缓存计算结果避免重复计算。

cdef class CachedClass:
cdef object _cache
cdef int _value
def __init__(self, int value):
self._value = value
self._cache = {}
cdef object _get_cached(self, str key):
if key not in self._cache:
self._cache[key] = self._compute(key)
return self._cache[key]
cdef object _compute(self, str key):
# 昂贵的计算
return self._value * len(key)

功能说明:Cython支持单继承,实现多态。

cdef class Animal:
cdef str _name
def __init__(self, str name):
self._name = name
cpdef str speak(self):
return "..."
cdef class Dog(Animal):
cdef str _breed
def __init__(self, str name, str breed):
super().__init__(name)
self._breed = breed
cpdef str speak(self):
return "Woof!"
cdef class Cat(Animal):
cpdef str speak(self):
return "Meow!"

输出示例:

>>> dog = Dog("Buddy", "Labrador")
>>> dog.speak()
'Woof!'
>>> cat = Cat("Whiskers")
>>> cat.speak()
'Meow!'

功能说明:Cython不支持多继承,使用组合替代。

# Cython不支持多继承
# cdef class A: pass
# cdef class B: pass
# cdef class C(A, B): # 错误
# 使用组合代替
cdef class A:
cdef int value_a
cdef class B:
cdef int value_b
cdef class C:
cdef A _a
cdef B _b
def __init__(self):
self._a = A()
self._b = B()

功能说明:通过方法检查模拟抽象类。

# Cython中没有抽象类的直接支持
# 使用方法检查
cdef class AbstractBase:
cpdef str operation(self):
raise NotImplementedError("Subclasses must implement")
cdef class Concrete(AbstractBase):
cpdef str operation(self):
return "Concrete implementation"

功能说明:在扩展类型中嵌入C结构体。

cdef struct Point3D:
double x
double y
double z
cdef class Vector:
cdef Point3D _origin
def __init__(self, double x, double y, double z):
self._origin.x = x
self._origin.y = y
self._origin.z = z
cpdef double magnitude(self):
return (self._origin.x ** 2 +
self._origin.y ** 2 +
self._origin.z ** 2) ** 0.5

输出示例:

>>> v = Vector(1.0, 2.0, 2.0)
>>> v.magnitude()
3.0

功能说明:使用packed确保结构体紧凑。

# 确保结构体紧凑(无padding)
cdef packed struct CompactPoint:
double x # 8字节
double y # 8字节
# 总共16字节,无padding
# 普通结构体可能有padding
cdef struct NormalPoint:
double x
double y
# 编译器可能添加padding对齐

功能说明:与C结构体互操作。

cdef extern from "myheader.h":
cdef struct NativePoint:
double x
double y
cdef class PyNativeBridge:
cdef NativePoint _native
def __init__(self, double x, double y):
self._native.x = x
self._native.y = y
cpdef (double, double) get_coords(self):
return (self._native.x, self._native.y)

功能说明:使用property定义属性访问逻辑。

cdef class Celsius:
cdef double _celsius
def __init__(self, double temp):
self._celsius = temp
property fahrenheit:
def __get__(self):
return self._celsius * 9.0/5.0 + 32.0
def __set__(self, double value):
self._celsius = (value - 32.0) * 5.0/9.0

输出示例:

>>> c = Celsius(100)
>>> c.fahrenheit
212.0
>>> c.fahrenheit = 32
>>> c._celsius
0.0

功能说明:实现__get__和__set__的描述符类。

cdef class RangeValidator:
cdef int _min
cdef int _max
def __init__(self, int min_val, int max_val):
self._min = min_val
self._max = max_val
def __get__(self, obj, objtype=None):
return obj._value if obj else self
def __set__(self, obj, value):
if value < self._min or value > self._max:
raise ValueError(f"Must be between {self._min} and {self._max}")
obj._value = value
cdef class Temperature:
cdef int _value
cdef RangeValidator _validator
def __init__(self, int initial=0):
self._value = initial
self._validator = RangeValidator(0, 100)

特性语法性能
cdef class扩展类型最快
cpdef双重可调用中
property属性访问Python开销
cdef structC结构体极快
  1. 类属性用cdef而非cdef public
  2. 方法优先用cdef,需要Python调用时用cpdef
  3. 继承只支持单继承,用组合替代多继承
  4. 资源管理用__cinit__和__dealloc__
  5. 频繁访问的属性用缓存

  1. 实现一个Complex复数类(支持加减乘除)
  2. 创建带惰性计算的类(缓存结果)
  3. 实现继承体系(Animal -> Dog, Cat)
  4. 使用C结构体嵌入表示几何对象
  5. 实现描述符进行输入验证(如范围检查)
  6. 比较cdef属性和cdef public属性的访问性能