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

Python继承内置类型搭配super使用时list与其他类型表现差异问题

问题成因

你遇到的差异本质是Python内置类型的初始化逻辑分为两类,且你采用的多继承方案受方法解析顺序(MRO)影响:

  • 不可变类型(int、str、tuple等):实例值的构造完全在__new__方法中完成,__init__方法继承自object,不接收额外参数,也不会修改实例值。你传入的初始化参数在__new__阶段就已经写入实例,因此哪怕你在Value.__init__中调用无参的super().__init__()也不会报错,实例值也正常。
  • 可变类型(list、dict、set等):__new__方法只会生成空的容器实例,元素填充逻辑在__init__方法中实现,必须传入初始化参数才能生成非空实例。你的Value.__init__调用无参super().__init__()时,父类的__init__没有拿到你传入的列表,因此最终生成空实例。

直接统一给super().__init__(value)传参会报错,是因为不可变类型的__init__不接收额外参数,传参就会触发类型错误。

推荐实现方案

提供两种可选方案,可根据你的使用场景选择:

方案1:代理模式(更稳妥,无兼容问题)

不需要继承内置类型,直接用属性转发模拟内置类型的所有行为,完全规避初始化逻辑差异问题:

class Value:
    def __init__(self, value, **extra_attrs):
        self._inner = value
        # 批量添加额外属性
        for k, v in extra_attrs.items():
            setattr(self, k, v)
    
    # 转发普通属性访问
    def __getattr__(self, item):
        return getattr(self._inner, item)
    
    # 转发容器操作的魔术方法,根据需要补充即可
    def __getitem__(self, item):
        return self._inner[item]
    def __setitem__(self, key, value):
        self._inner[key] = value
    def __delitem__(self, key):
        del self._inner[key]
    def __len__(self):
        return len(self._inner)
    def __repr__(self):
        return repr(self._inner)
    def __add__(self, other):
        return self._inner + other

使用时不需要动态构造多继承类,直接传入对应值即可:

# 模拟int类型
var1 = Value(1, extra_tag="test_int")
print(var1 + 2) # 输出3,和普通int行为一致
print(var1.extra_tag) # 输出test_int,可正常访问额外属性

# 模拟list类型
var2 = Value(['some', 'list'], extra_tag="test_list")
print(var2[0]) # 输出some,和普通list行为一致
var2.append('new')
print(var2) # 输出['some', 'list', 'new']

方案2:继承方案(适配需要完全兼容内置类型特性的场景)

如果必须用多继承的实现方式,可直接判断实例所属的父类类型,覆盖所有常用可变容器类型即可,不需要判断参数类型:

class Value:
    def __init__(self, value, *args, **kwargs):
        # 仅可变容器类型需要传入参数调用父类__init__
        mutable_types = (list, dict, set, bytearray)
        if isinstance(self, mutable_types):
            super().__init__(value, *args, **kwargs)
        else:
            super().__init__()
        # 你的额外初始化逻辑写在这里

你原来动态构造类的代码不需要修改,即可同时兼容可变、不可变内置类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 00:15:03