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

继承bitstring.BitArray时子类构造函数首参数被父类误用的原因与解决方法

自定义类继承BitArray时构造函数的参数问题

自定义类继承bitstring库的BitArray类时,遇到构造函数参数异常:子类定义的第一个位置参数总是被父类BitArray的构造函数占用,导致预期行为不符。

示例代码

from bitstring import BitArray

class MyClass(BitArray):
    def __init__(self, var1, kwvar1=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.var1 = var1
        self.kwvar1 = kwvar1


a = MyClass('0xff', kwvar1="myvar")
print(a.b) # 预期为空
print(a.var1)
print(a.kwvar1)

实际输出

11111111
0xff
myvar

按预期a.b应为空,但实际得到了由'0xff'初始化的全1BitArray。

额外参数传入时的错误

若执行:

a = MyClass('0xff','0x0f0f', kwvar1="myvar")

会触发KeyError:

C:\Python\Python311\Lib\site-packages\bitstring.py", line 964, in __new__
    return _cache[auto]
           ~~~~~~^^^^^^
KeyError: '0xff'

预期a.b应返回0000111100001111(对应0x0f0f),但实际报错。


问题根源

BitArray是依赖__new__方法完成实例创建的类型,而非普通类的__init__。当创建子类实例时,Python会优先调用父类的__new__方法,且__new__会接收所有传入的参数——包括你想留给子类的var1。

你之前只重写了__init__,但此时实例已经被父类__new__用第一个位置参数初始化完成,super().__init__(*args, **kwargs)的调用实际没有起到预期的初始化作用,因为BitArray的核心初始化逻辑在__new__中。

解决方案

需要重写子类的__new__方法,先提取子类专属的参数,再将剩余参数传递给父类的__new__:

from bitstring import BitArray

class MyClass(BitArray):
    def __new__(cls, var1, kwvar1=None, *args, **kwargs):
        # 先调用父类__new__创建实例,传入剩余参数
        obj = super().__new__(cls, *args, **kwargs)
        # 给实例绑定子类属性
        obj.var1 = var1
        obj.kwvar1 = kwvar1
        return obj

# 测试验证
a = MyClass('0xff', kwvar1="myvar")
print(a.b)  # 输出空字符串,符合预期
print(a.var1)  # 输出0xff
print(a.kwvar1)  # 输出myvar

b = MyClass('custom_data', '0x0f0f', kwvar1="test")
print(b.b)  # 输出0000111100001111
print(b.var1)  # 输出custom_data

补充说明

  • 若想彻底避免参数冲突,也可以将子类的所有参数设为关键字参数,比如def __new__(cls, *, var1, kwvar1=None, *args, **kwargs),强制调用者用关键字传递子类参数,避免和父类的位置参数混淆。
  • 之前的KeyError是因为父类__new__将'0xff'当作初始化参数处理,但该值不在BitArray的缓存键或支持的初始化格式中,导致报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 08:10:23