Python带参数super()理解误区:多继承代码报错原因咨询
Python多继承中super()与父类__init__调用的错误分析
我是编程新手,之前以为Python里的super()方法等同于super(<类名>, self),所以在多继承场景下,想通过给super()传入指定类来调用对应父类的方法,但实际这么写的时候出现了看不懂的报错。下面是我尝试的几段报错代码及具体问题:
第一段报错代码及问题
class Employee: new_id = 1 def __init__(self): self.id = Employee.new_id Employee.new_id += 1 class User: def __init__(self, username, role="Customer"): self.username = username self.role = role class Admin(Employee,User): def __init__(self): super(Employee,self).__init__() super(User,self).__init__(self,self.id,'admin') e1 = Employee() e2 = Employee() e3 = Admin()
错误原因:
super(Employee, self).__init__()逻辑错误:Python的super(class, instance)会从该类在MRO(方法解析顺序)中的下一个类开始查找方法。Admin的MRO是[Admin, Employee, User, object],所以super(Employee, self)实际指向User类,调用User.__init__时未传必要的username参数,触发TypeError。super(User, self).__init__(self,self.id,'admin')双重错误:super(User, self)指向object类,而object.__init__不需要参数;另外就算能指向User,super绑定的方法也不需要手动传self,super会自动绑定实例传递该参数。
第二段报错代码及问题
class Employee: new_id = 1 def __init__(self): self.id = Employee.new_id Employee.new_id += 1 class User: def __init__(self, username, role="Customer"): self.username = username self.role = role class Admin(Employee,User): def __init__(self): Employee.__init__() User.__init__(self,self.id,'admin') e1 = Employee() e2 = Employee() e3 = Admin()
错误原因:
Employee.__init__()未传self:直接调用父类未绑定方法时,必须显式传递实例self,否则__init__里的self.id找不到对应实例,触发TypeError: __init__() missing 1 required positional argument: 'self'。User.__init__(self,self.id,'admin')参数数量错误:User.__init__定义只需要self(自动传递时,实际传入username和可选role),这里传了三个参数,相当于给方法传了4个位置参数(含默认的self),超出定义数量,触发TypeError。
第三段报错代码及问题
class Employee: new_id = 1 def __init__(self): self.id = Employee.new_id Employee.new_id += 1 class User: def __init__(self, username, role="Customer"): self.username = username self.role = role class Admin(Employee,User): def __init__(self): super().__init__() User.__init__(self.id,'admin')
错误原因:
User.__init__(self.id,'admin')未传self:调用未绑定的User.__init__时,必须把当前实例self作为第一个参数传入,否则方法内部无法访问实例属性,触发TypeError: __init__() missing 1 required positional argument: 'self'。
正确的实现方式
如果要在多继承中正确初始化两个父类的属性,可以这样写:
class Employee: new_id = 1 def __init__(self): self.id = Employee.new_id Employee.new_id += 1 class User: def __init__(self, username, role="Customer"): self.username = username self.role = role class Admin(Employee, User): def __init__(self): # 调用Employee的__init__初始化id super().__init__() # 显式调用User的__init__,传入self和必要参数 User.__init__(self, str(self.id), 'admin') e1 = Employee() e2 = Employee() e3 = Admin() print(e3.id, e3.username, e3.role) # 输出:3 3 admin
内容的提问来源于stack exchange,提问作者gix
相关产品推荐
相关产品推荐

