为了账号安全,请及时绑定邮箱和手机立即绑定

关于多重继承在子类的__init__方法中到底应该调用哪个父类的__init__

我想问下 假设 C继承了A和B  其中A的init有两个参数,B的init有三个参数,这几个参数都没有啥特别的关系,然后我在写C的init函数的时候,里面的super应该咋写,到底以哪个父类的为准。这块儿我比较疑惑。

正在回答

3 回答

# 关于你这个情况,我尝试了两种理解方法,我自己称为显示调用和继承式调用,具体代码如下:


class Person(object):

    def __init__(self, name, gender):

        self.name = name

        self.gender = gender



class Student(Person):

    def __init__(self, name, gender, score):

        super(Student, self).__init__(name, gender)

        self.score = score



class Teacher(Person):

    def __init__(self, name, gender, course):

        super(Teacher, self).__init__(name, gender)

        self.course = course



class Skill(object):

    def __init__(self, sport):

        self.sport = sport



class PlayBasketball(Skill):

    def __init__(self, sport):

        super(PlayBasketball, self).__init__(sport)



class PlayFootball(Skill):

    def __init__(self, sport):

        super(PlayFootball, self).__init__(sport)



# 显示地调用父类的init初始化方法

class StudentBasketball(PlayBasketball, Student):

    def __init__(self, name, gender, score, sport):

        Student.__init__(self, name, gender, score)

        PlayBasketball.__init__(self, sport)


    def can_play(self):

        return 'I am %s ,i am %s, i got score %s ,i can play%s' % (self.name, self.gender, self.score, self.sport)



# 显示地调用父类的init初始化方法

class TeacherFootball(PlayFootball, Teacher):

    def __init__(self, name, gender, course, sport):

        Teacher.__init__(self, name, gender, course)

        PlayFootball.__init__(self, sport)


    def can_play(self):

        return 'I am %s ,i am %s,i teach %s ,i can play%s' % (self.name, self.gender, self.course, self.sport)



# 继承式地调用父类的init初始化方法

class StudentPlayBasketball(PlayBasketball, Student):

    def __init__(self, name, gender, score, sport):

        super(StudentPlayBasketball, self).__init__(name, gender, score)

        super(StudentPlayBasketball, self).__init__(sport)


    def can_play(self):

        return 'I am %s ,i am %s, i got score %s ,i can play%s' % (self.name, self.gender, self.score, self.sport)



# 继承式地调用父类的init初始化方法

class TeacherPlayFootball(PlayFootball, Teacher):

    def __init__(self, name, gender, course, sport):

        super(TeacherPlayFootball, self).__init__(name, gender, course)

        super(TeacherPlayFootball, self).__init__(sport)


    def can_play(self):

        return 'I am %s ,i am %s,i teach %s ,i can play%s' % (self.name, self.gender, self.course, self.sport)



student = StudentBasketball('Jason', 'Male', 98, 'Basketball')

teacher = TeacherFootball('Alice', 'Female', 'English', 'Football')


student1 = StudentBasketball('Jason', 'Male', 98, 'Basketball')

teacher2 = TeacherFootball('Alice', 'Female', 'English', 'Football')


print(student1.can_play())

print(teacher2.can_play())


0 回复 有任何疑惑可以回复我~

在Python中,当类C继承自类A和类B,并且A和B的__init__方法需要不同数量的参数时,你需要在类C的__init__方法中显式地调用这两个父类的__init__方法。由于Python的super()函数用于调用父类的方法,但它不会自动处理不同数量的参数问题,因此你需要手动调用每个父类的__init__方法,并传递必要的参数。

以下是一个例子,展示了如何在类C的__init__方法中调用类A和类B的__init__方法:

class A:  
    def __init__(self, name, age):  
        self.name = name  
        self.age = age  
  
class B:  
    def __init__(self, name, sex, height):  
        self.name = name  
        self.sex = sex  
        self.height = height  
  
class C(A, B):  
    def __init__(self, name, age, sex, height):  
        # 显式调用A的__init__方法  
        A.__init__(self, name, age)  
        # 显式调用B的__init__方法  
        B.__init__(self, name, sex, height)  
  
# 创建C的实例  
c = C("Alice", 30, "female", 165)  
print(c.name)  # 输出: Alice  
print(c.age)   # 输出: 30  
print(c.sex)   # 输出: female  
print(c.height) # 输出: 165

在上面的例子中,类C的__init__方法接受所有必要的参数,然后分别调用类A和类B的__init__方法。注意,这里我们直接调用了A和B的__init__方法,而不是使用super()。这是因为super()用于调用当前类在MRO(方法解析顺序)中的下一个父类的方法,但它不会处理不同数量的参数问题。由于类A和类B的__init__方法需要不同的参数集,直接调用它们是最直接和清晰的方式。

如果你坚持想要使用super(),那么你必须确保你的继承结构以及__init__方法的参数设计允许这样做。这通常意味着你需要设计一个统一的参数列表,这个列表可以包含所有父类__init__方法所需的参数。然而,在你的情况下,由于参数之间没有直接的关系,并且它们各自属于不同的父类,这可能会变得非常复杂且不直观。因此,直接调用每个父类的__init__方法通常是更合适的选择。


0 回复 有任何疑惑可以回复我~

我所理解的格式是这样的,希望对你有帮助:

class 本类名(父类名)

    del __init__(所有属性(包括新属性)):

        super (本类名,self).__init__(父类拥有的属性)

        self.新属性1 = 新属性1

0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

关于多重继承在子类的__init__方法中到底应该调用哪个父类的__init__

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信