TypeError: super(type, obj): obj must be an instance or subtype of type

本文介绍了在Python编程中遇到的`TypeError: super(type, obj): obj must be an instance or subtype of type`错误。问题源于在成员函数中使用super()进行列表解析时,导致的参数问题。通过三种解决方案来解决这个问题:使用`cls`代替`super()`, 使用常规for循环避免解析式中调用`super()`, 或者不使用解析式并在外部调用`super()`。" 46728347,927068,清理MySQL Sleep连接,"['MySQL管理', '数据库优化', '系统维护', 'shell脚本', 'PHP']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

今天学习《Python Web 开发实战》自定义转换器这一小节,书中有段代码如下:

class ListConverter(BaseConverter):

    def __init__(self, url_map, separator="+"):
        super(ListConverter, self).__init__(url_map)
        self.separator = urllib.parse.unquote(separator)

    def to_python(self, value):
        return value.split(self.separator)

    def to_url(self, values):
        return self.separator.join(super(ListConverter, self).to_url(value)
                                   for value in values)

倒没什么问题,是可以正常运行的。

然而我对 super() 的用法不是很满意,毕竟在 Python3 环境下开发,super(ListConverter, self) 有硬编码嫌疑。于是代码修改如下:

class ListConverter(BaseConverter):

    def __init__(self, url_map, separator="+"):
        super().__init__(url_map)
        self.separator = urllib.parse.unquote(separator)

    def to_python(self, value):
        return value.split(self.separator)

    def to_url(self, values):
        return self.separator.join(super().to_url(value)
                                   for value in values)

结果一运行,解释器报错如下:
TypeError: super(type, obj): obj must be an instance or subtype of type

原因

经过多次尝试,发现问题出现在 self.separator.join(super().to_url(value) for value in values) 这段代码里。于是我做了个测试。

class A(object):
    def print_what(self, what):
        print(what)

class B(A):
    def print_what(self, what):
        [super() for __ in range(5)]

if __name__ == "__main__":
    b = B()
    b.print_what("hello")

------------------------------------
TypeError: super(type, obj): obj must be an instance or subtype of type

果然异常,当我将 super() 改为 super(B, self) 又一切正常。

是因为 super() 在一个成员函数中多次调用造成的吗?那就不用列表解析式,换寻常的循环语句:

class B(A):
    def print_what(self, what):
        for __ in range(5):
            super()

结果运行正常。

事实上,在成员函数中使用 super() 时,Python 会自动传参,我猜测是解析式影响了传进去的参数。但遗憾的是,我不知道该如何调试,才能获得错误情况下,传进去的参数是什么。

解决方案

针对此次遇到的问题,解决方法有以下三种。

第一种

使用 super(ListConverter, self) 代替 super()

第二种

不用解析式,用寻常的 for 循环。

class ListConverter(BaseConverter):
    ...
    def to_url(self, values):
        tmplist = []
        for value in values:
            tmplist.append(super().to_url(value))
        return self.separator.join(tmplist)

第三种

使用解析式,但不在解析式中调用 super()。

class ListConverter(BaseConverter):
    ...
    def to_url(self, values):
        sup = super()
        return self.separator.join(sup.to_url(value)
                                   for value in values)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值