You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cython中子类化int实现BitSet类?解决__new__编译报错

Cython化继承自int的BitSet类实现方案

解决__new__编译错误:改用__cinit__

Cython中扩展类型(cdef class)继承内置类型(如int)时,直接使用__new__会触发语义变更的编译警告。正确方案是用__cinit__替代——这是C级别构造函数,负责实例的底层初始化,每次创建实例都会被调用且无法被重写,刚好适配BitSet从输入列表计算初始整数值的场景。

示例初始化实现:

cdef class BitSet(int):
    def __cinit__(self, list bits=None):
        cdef int val = 0
        cdef int bit
        # 处理输入位列表,计算对应整数值
        if bits is not None:
            for bit in bits:
                if bit < 0:
                    raise ValueError("Bit position cannot be negative")
                val |= 1 << bit
        # 初始化父类int的底层数值
        self.base = val

关于__cinit__与__init__的分工:

  • __cinit__:负责C级内存分配、基础值初始化,必须执行,适合处理必填参数和底层逻辑。
  • __init__:Python级初始化,在__cinit__之后调用,可选,适合处理可选参数、Python端额外配置(无需修改底层值的场景)。

实现集合相关方法

根据需求实现集合类核心方法,示例如下:

长度与布尔判断

def __len__(self):
    # 返回最高位位置+1,空BitSet返回0
    cdef int val = self
    cdef int length = 0
    if val == 0:
        return 0
    while val > 0:
        length += 1
        val >>= 1
    return length

def __bool__(self):
    # 判断是否有位被设置
    return self != 0

迭代与成员判断

def __iter__(self):
    # 遍历所有被设置的位
    cdef int val = self
    cdef int bit = 0
    while val > 0:
        if val & 1:
            yield bit
        val >>= 1
        bit += 1

def __contains__(self, object bit):
    # 判断指定位是否存在
    if not isinstance(bit, int):
        raise TypeError("Bit position must be integer")
    if bit < 0:
        return False
    return (self & (1 << bit)) != 0

集合运算(以差集__sub__为例)

先实现类方法方便从int直接创建BitSet,避免重复初始化逻辑:

@classmethod
def from_int(cls, int val):
    # 从整数值直接创建BitSet实例
    cdef BitSet bs = cls.__new__(cls)
    bs.base = val
    return bs

再实现差集及其他集合运算:

def __sub__(self, BitSet other):
    # 集合差集:self存在但other不存在的位
    return BitSet.from_int(self & ~other)

def __and__(self, BitSet other):
    # 集合交集
    return BitSet.from_int(self & other)

def __or__(self, BitSet other):
    # 集合并集
    return BitSet.from_int(self | other)

禁用int的不适用方法

对int中不符合BitSet语义的方法(如__float__、__neg__、__pow__等),直接重写并抛出错误:

def __float__(self):
    raise TypeError("BitSet cannot be converted to float")

def __neg__(self):
    raise TypeError("BitSet does not support negation")

def __pow__(self, object other, object mod=None):
    raise TypeError("BitSet does not support exponentiation")

# 可按需添加更多禁用方法,如__truediv__、__div__等

内容的提问来源于stack exchange,提问作者PlasmaBinturong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 17:04:55