Python多继承之super()继承问题解决

  • 在继承问题之前先来了解下:super是什么?(后面继承代码会用到)
    • 严格来说:super () 不是方法,它是一个 !是用来创建 代理对象 的内置类!

    • super() 是 Python 内置的 类(class) ,调用 super() 其实是在 创建一个 super 对象

      python 复制代码
      # 来看下这个是什么意思?
      super().__init__()
      
      # 1.super() 创建一个代理对象
      # 2.这个对象自动帮你找到父类
      # 3.然后调用父类的 __init__ 方法

接下来进入正题,看下面代码为什么会报错?

python 复制代码
# 爷爷类:基础用户(所有用户都有的属性)
class User:
    def __init__(self, username, password):
        self.username = username
        self.password = password

# 父类1:会员用户
class MemberUser(User):
    def __init__(self, username, password, vip_level):
        # 注意这里的 super() 会自动按 MRO 顺序调用
        super().__init__(username, password)
        self.vip_level = vip_level

# 父类2:管理员用户
class AdminUser(User):
    def __init__(self, username, password, role):
        # 注意这里的 super() 会自动按 MRO 顺序调用
        super().__init__(username, password)
        self.role = role

# 子类:超级用户(多继承 → 既是会员,又是管理员)
class SuperUser(MemberUser, AdminUser):
    def __init__(self, username, password, vip_level, role):
        # 手动初始化两个父类
        MemberUser.__init__(self, username, password, vip_level)
        AdminUser.__init__(self, username, password, role)

super_user = SuperUser('test', '123456', '3', 'test_user')

报错信息:TypeError: AdminUser.init () missing 1 required positional argument: 'role'。 AdminUser类 为什么会缺少一个位置参数呢?

  • 第一步:我们从头开始捋

    • 代码从实例化 SuperUser 子类开始
    • SuperUser 又是多继承
    • 那么我们来看 SuperUser 子类的mro顺序,也就是继承的顺序,也就是 super() 代理对象 的顺序,这个很关键!
    python 复制代码
    # 以下两种打印方式都可以
    # print(SuperUser.__mro__)  # 这种打印出来是元组
    print(SuperUser.mro())  # 这种打印出来是列表,这里用这个了
    # 打印结果:
    # [<class '__main__.SuperUser'>, <class '__main__.MemberUser'>, <class '__main__.AdminUser'>, <class '__main__.User'>, <class 'object'>]
    # 这里继承的顺序很关键:SuperUser -- MemberUser -- AdminUser -- User -- object
  • 第二步:我们知道了继承的顺序,先是 SuperUser 本身,这里没什么问题,然后是MemberUser ,再然后是 AdminUser ... 此时我们来看下 MemberUser 中的代码!

    python 复制代码
    # 父类1:会员用户
    class MemberUser(User):
        def __init__(self, username, password, vip_level):
            # 注意这里的 super() 会自动按 MRO 顺序调用
            super().__init__(username, password)
            self.vip_level = vip_level
            
    # mro继承顺序很关键:SuperUser -- MemberUser -- AdminUser -- User -- object
    • 问题关键:
      • 来看下上面代码的super()

      • 我们的本意是要让他调用 User 爷爷类的初始化方法

      • 但是现在按照mro顺序实际找的是 MemberUser 下一个类 ,也就是 AdminUser

      • 相当于这里的 super() 调用的是 AdminUser 类中的 初始化方法

      • AdminUser 中的__init__需要三个参数 ,但是 MemberUser 中 super() 调用的时候传了两个 ,所以缺少了一个参数,所以报错了

        python 复制代码
        # 父类2:管理员用户
        class AdminUser(User):
            def __init__(self, username, password, role):
                # 注意这里的 super() 会自动按 MRO 顺序调用
                super().__init__(username, password)
                self.role = role
  • 第三步:解决问题

    • 通过父类名方式调用父类方法,让 MemberUser 和 AdminUser 中的 super() 去找 User
  • 第四步:解决后的完整代码

    python 复制代码
    # 爷爷类:基础用户(所有用户都有的属性)
    class User:
        def __init__(self, username, password):
            self.username = username
            self.password = password
    
    # 父类1:会员用户
    class MemberUser(User):
        def __init__(self, username, password, vip_level):
            # 注意这里的 super() 会自动按 MRO 顺序调用
            # super().__init__(username, password)
            # 将这里的 super() 改为 User, 注意改成这种方式后,要传递self
            User.__init__(self, username, password)
            self.vip_level = vip_level
            
    # 父类2:管理员用户
    class AdminUser(User):
        def __init__(self, username, password, role):
            # 注意这里的 super() 会自动按 MRO 顺序调用
            # super().__init__(username, password)
            # 将这里的 super() 改为 User, 注意改成这种方式后,要传递self
            User.__init__(self, username, password)
            self.role = role
    
    # 子类:超级用户(多继承 → 既是会员,又是管理员)
    class SuperUser(MemberUser, AdminUser):
        def __init__(self, username, password, vip_level, role):
            # 手动初始化两个父类
            MemberUser.__init__(self, username, password, vip_level)
            AdminUser.__init__(self, username, password, role)
    
    super_user = SuperUser('test', '123456', '3', 'test_user')
相关推荐
玫幽倩1 小时前
2026盘古石取证决赛(APK取证)
数据库·python·电子取证·aes·隐藏·笔记软件·手机取证
迈巴赫车主1 小时前
蓝桥杯21241灯塔java
java·开发语言·数据结构·算法·职场和发展·蓝桥杯·动态规划
装不满的克莱因瓶1 小时前
基于 Python 进行二维空间线性可分数据单/多层感知器实战
人工智能·python·深度学习·神经网络·ai·卷积
2601_950368911 小时前
稀土合金粉末采购指南:3步筛选靠谱镁钆供应商
大数据·运维·人工智能·python
半个烧饼不加肉1 小时前
JS 底层探究-- 调用栈(Call Stack)
开发语言·前端·javascript
弹简特2 小时前
【Java项目-轻聊】08-用户管理模块-实现获取用户信息+头像上传+显示头像
java·开发语言·springboot
vickycheung32 小时前
RK182X 如何在 RK3588 上进行应用测试
开发语言·php
至天2 小时前
FastAPI 接入 FastAPI-Limiter 以及使用 Redis 进行限流指南
redis·python·fastapi·请求限流
财经资讯数据_灵砚智能2 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年6月4日
人工智能·python·ai·信息可视化·自然语言处理·ai编程·灵砚智能