Python继承frozenset重写构造方法报TypeError的原因与解决方法
异常触发原因
frozenset是Python内置的不可变集合类型,所有Python内置不可变类型(包括int、str、tuple、frozenset)的实例值初始化逻辑都不放在__init__方法中,而是在__new__方法(实例创建阶段)就完成值的绑定——毕竟不可变对象一旦创建完成就不能修改内容,等执行到__init__时实例已经生成、处于不可变状态,根本没法再修改集合内的元素。
你写的代码有两个核心问题:
- frozenset本身的
__init__方法直接继承自顶层object类,除了self参数外不接收任何其他传入值,你在__init__中调用super().__init__([1,2,3])相当于给object的__init__多传了一个列表参数,正好触发你看到的TypeError。 - 你把初始化集合元素的逻辑写在
__init__里,就算不报错,也没法修改已经创建完成的frozenset实例的内容,根本达不到预期效果。
正确修复方案
继承frozenset这类不可变内置类型时,涉及实例初始值设置的逻辑要重写__new__方法实现,基础修复代码如下:
class B(frozenset): def __new__(cls): # __new__是类级别的实例创建方法,需要返回生成的实例对象 return super().__new__(cls, [1, 2, 3])
此时实例化测试就可以正常运行:
b = B() print(b) # 输出: frozenset({1, 2, 3})
如果要实现你需要的单例模式frozenset,只需要在__new__方法中增加实例缓存逻辑即可:
class SingletonFrozenset(frozenset): _instance = None # 类属性缓存单例实例 def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls, [1, 2, 3]) return cls._instance
验证单例效果:
s1 = SingletonFrozenset() s2 = SingletonFrozenset() print(s1 is s2) # 输出: True,两次实例化拿到的是同一个对象 print(s1) # 输出: frozenset({1, 2, 3})
注意:不要在子类的
__init__方法中给父类__init__传递集合元素相关的参数,frozenset的__init__不处理这类入参,传参就会触发参数不匹配的报错。
内容的提问来源于stack exchange,提问作者CrabMan
相关产品推荐
相关产品推荐

