继承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
相关产品推荐
相关产品推荐

