Python多继承之super()继承问题解决
在继承问题之前先来了解下super是什么后面继承代码会用到严格来说super () 不是方法它是一个类是用来创建代理对象的内置类super() 是 Python 内置的类class调用 super() 其实是在 创建一个super 对象# 来看下这个是什么意思super().__init__()# 1.super() 创建一个代理对象# 2.这个对象自动帮你找到父类# 3.然后调用父类的 __init__ 方法接下来进入正题看下面代码为什么会报错?# 爷爷类基础用户所有用户都有的属性classUser:def__init__(self,username,password):self.usernameusername self.passwordpassword# 父类1会员用户classMemberUser(User):def__init__(self,username,password,vip_level):# 注意这里的 super() 会自动按 MRO 顺序调用super().__init__(username,password)self.vip_levelvip_level# 父类2管理员用户classAdminUser(User):def__init__(self,username,password,role):# 注意这里的 super() 会自动按 MRO 顺序调用super().__init__(username,password)self.rolerole# 子类超级用户多继承 → 既是会员又是管理员classSuperUser(MemberUser,AdminUser):def__init__(self,username,password,vip_level,role):# 手动初始化两个父类MemberUser.__init__(self,username,password,vip_level)AdminUser.__init__(self,username,password,role)super_userSuperUser(test,123456,3,test_user)报错信息TypeError: AdminUser.init() missing 1 required positional argument: ‘role’。AdminUser类 为什么会缺少一个位置参数呢第一步我们从头开始捋代码从实例化 SuperUser 子类开始SuperUser 又是多继承那么我们来看 SuperUser 子类的mro顺序也就是继承的顺序也就是super() 代理对象的顺序这个很关键# 以下两种打印方式都可以# 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中的代码# 父类1会员用户classMemberUser(User):def__init__(self,username,password,vip_level):# 注意这里的 super() 会自动按 MRO 顺序调用super().__init__(username,password)self.vip_levelvip_level# mro继承顺序很关键SuperUser -- MemberUser -- AdminUser -- User -- object问题关键来看下上面代码的super()我们的本意是要让他调用 User 爷爷类的初始化方法但是现在按照mro顺序实际找的是 MemberUser 下一个类也就是AdminUser类相当于这里的 super() 调用的是 AdminUser 类中的 初始化方法AdminUser 中的__init__需要三个参数但是 MemberUser 中 super() 调用的时候传了两个所以缺少了一个参数所以报错了# 父类2管理员用户classAdminUser(User):def__init__(self,username,password,role):# 注意这里的 super() 会自动按 MRO 顺序调用super().__init__(username,password)self.rolerole第三步解决问题通过父类名方式调用父类方法让 MemberUser 和 AdminUser 中的 super() 去找 User第四步解决后的完整代码# 爷爷类基础用户所有用户都有的属性classUser:def__init__(self,username,password):self.usernameusername self.passwordpassword# 父类1会员用户classMemberUser(User):def__init__(self,username,password,vip_level):# 注意这里的 super() 会自动按 MRO 顺序调用# super().__init__(username, password)# 将这里的 super() 改为 User, 注意改成这种方式后要传递selfUser.__init__(self,username,password)self.vip_levelvip_level# 父类2管理员用户classAdminUser(User):def__init__(self,username,password,role):# 注意这里的 super() 会自动按 MRO 顺序调用# super().__init__(username, password)# 将这里的 super() 改为 User, 注意改成这种方式后要传递selfUser.__init__(self,username,password)self.rolerole# 子类超级用户多继承 → 既是会员又是管理员classSuperUser(MemberUser,AdminUser):def__init__(self,username,password,vip_level,role):# 手动初始化两个父类MemberUser.__init__(self,username,password,vip_level)AdminUser.__init__(self,username,password,role)super_userSuperUser(test,123456,3,test_user)