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

Python扩展内置list方法时list.append()调用报错原因

super()调用父类方法与直接类名调用的差异及报错原因

首先给出问题复现代码:

class EvenOnly(list):
    def append(self, integer):
        if not isinstance(integer, int):
            raise TypeError(f"'{integer}' is not an integer.")
        if integer % 2:
            raise ValueError(f"'{integer}' is not an even integer")
        super().append(integer)

将末尾的super().append(integer)替换为list.append(integer)后,执行会抛出如下错误:

TypeError: descriptor 'append' for 'list' objects doesn't apply to a 'int' object

两种调用方式的核心区别

  • super().append(integer):super()会返回一个绑定了当前类实例self的特殊代理对象,调用代理对象的方法时,会自动将self作为第一个隐式参数传入父类方法,实际执行的传参是list.append(self, integer),完全符合实例方法的传参规则。
  • list.append(integer):这是直接通过类名访问类上定义的未绑定实例方法,不会自动绑定当前实例,调用时不会隐式传入self,此时你只传入了一个参数integer,缺失了实例方法必需的实例参数。

报错的根本原因

Python里类中定义的实例方法本身是实现了描述符协议的对象,通过类名直接访问实例方法时,拿到的是未绑定的原始方法,它要求第一个位置参数必须是该类(或其子类)的实例,之后才是方法接收的业务参数。
list的append方法真实签名是append(self, value):

  1. 当你写list.append(integer)时,Python会把你传入的唯一参数integer(int类型),当做方法要求的第一个参数self做类型校验
  2. 校验发现传入的self是int类型,不是list类的实例,就会抛出描述符不匹配的类型错误。

如果一定要显式指定父类调用方法,正确写法是手动传入当前实例self:

list.append(self, integer)

注意这种写法在多继承场景下不会遵循Python的MRO(方法解析顺序)链路,可能跳过MRO中其他协作类的同名方法逻辑,除非明确需要跳过MRO,否则日常开发优先使用super()做父类方法调用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:01:06