Hướng dẫn python multiple inheritance super - python đa thừa kế siêu

Tổng thể

Giả sử mọi thứ đi xuống từ

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
2 (bạn tự mình nếu không), Python tính toán một thứ tự phân giải phương thức (MRO) dựa trên cây kế thừa lớp của bạn. MRO thỏa mãn 3 thuộc tính:

Show
  • Trẻ em của một lớp đến trước cha mẹ của họ
  • Cha mẹ rời đi trước khi cha mẹ phải
  • Một lớp chỉ xuất hiện một lần trong MRO

Nếu không có thứ tự như vậy tồn tại, lỗi Python. Các hoạt động bên trong của điều này là một lớp lót C3 của tổ tiên. Đọc tất cả về nó ở đây: https://www.python.org/doad/releases/2.3/mro/

Khi một phương thức được gọi, lần xuất hiện đầu tiên của phương pháp đó trong MRO là phương pháp được gọi là. Bất kỳ lớp nào không thực hiện phương pháp đó đều bị bỏ qua. Bất kỳ cuộc gọi nào đến

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
3 trong phương thức đó sẽ gọi sự xuất hiện tiếp theo của phương thức đó trong MRO. Do đó, nó quan trọng cả thứ mà bạn đặt các lớp trong kế thừa và nơi bạn thực hiện các cuộc gọi đến
(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
3 trong các phương thức.

Lưu ý rằng bạn có thể thấy MRO trong Python bằng cách sử dụng phương thức

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
5.

Ví dụ

Tất cả các ví dụ sau đây có một kế thừa kim cương của các lớp như vậy:

    Parent
    /   \
   /     \
Left    Right
   \     /
    \   /
    Child

MRO là:

  1. Đứa trẻ
  2. Bên trái
  3. Đúng
  4. Cha mẹ

Bạn có thể kiểm tra điều này bằng cách gọi

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
6, trả về:

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)

Với (__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object) 3 đầu tiên trong mỗi phương thức

class Parent(object):
    def __init__(self):
        super(Parent, self).__init__()
        print("parent")

class Left(Parent):
    def __init__(self):
        super(Left, self).__init__()
        print("left")

class Right(Parent):
    def __init__(self):
        super(Right, self).__init__()
        print("right")

class Child(Left, Right):
    def __init__(self):
        super(Child, self).__init__()
        print("child")

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
8 Đầu ra:

parent
right
left
child
    

Với (__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object) 3 cuối cùng trong mỗi phương thức

class Parent(object):
    def __init__(self):
        print("parent")
        super(Parent, self).__init__()

class Left(Parent):
    def __init__(self):
        print("left")
        super(Left, self).__init__()

class Right(Parent):
    def __init__(self):
        print("right")
        super(Right, self).__init__()

class Child(Left, Right):
    def __init__(self):
        print("child")
        super(Child, self).__init__()

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
8 Đầu ra:

child
left
right
parent

parent right left child

Với

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
3 cuối cùng trong mỗi phương thức

class Parent(object):
    def __init__(self):
        print("parent")
        super(Parent, self).__init__()

class Left(Parent):
    def __init__(self):
        print("left")

class Right(Parent):
    def __init__(self):
        print("right")
        super(Right, self).__init__()

class Child(Left, Right):
    def __init__(self):
        print("child")
        super(Child, self).__init__()

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
8 Đầu ra:

child
left

parent
right
left
child
    

class Parent(object):
    def __init__(self):
        print("parent")
        super(Parent, self).__init__()

class Left(Parent):
    def __init__(self):
        print("left")
        super(Left, self).__init__()

class Right(Parent):
    def __init__(self):
        print("right")

class Child(Left, Right):
    def __init__(self):
        print("child")
        super(Child, self).__init__()

Với

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
3 cuối cùng trong mỗi phương thức

Khi không phải tất cả các lớp đều gọi
(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
3

Lệnh kế thừa quan trọng nhất nếu không phải tất cả các lớp trong chuỗi kế thừa gọi (__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object) 3. Ví dụ: nếu class Parent(object): def __init__(self): super(Parent, self).__init__() print("parent") class Left(Parent): def __init__(self): super(Left, self).__init__() print("left") class Right(Parent): def __init__(self): super(Right, self).__init__() print("right") class Child(Left, Right): def __init__(self): super(Child, self).__init__() print("child") 3 không gọi Super, thì phương thức trên class Parent(object): def __init__(self): super(Parent, self).__init__() print("parent") class Left(Parent): def __init__(self): super(Left, self).__init__() print("left") class Right(Parent): def __init__(self): super(Right, self).__init__() print("right") class Child(Left, Right): def __init__(self): super(Child, self).__init__() print("child") 4 và class Parent(object): def __init__(self): super(Parent, self).__init__() print("parent") class Left(Parent): def __init__(self): super(Left, self).__init__() print("left") class Right(Parent): def __init__(self): super(Right, self).__init__() print("right") class Child(Left, Right): def __init__(self): super(Child, self).__init__() print("child") 5 không bao giờ được gọi:

Ngoài ra, nếu

class Parent(object):
    def __init__(self):
        super(Parent, self).__init__()
        print("parent")

class Left(Parent):
    def __init__(self):
        super(Left, self).__init__()
        print("left")

class Right(Parent):
    def __init__(self):
        super(Right, self).__init__()
        print("right")

class Child(Left, Right):
    def __init__(self):
        super(Child, self).__init__()
        print("child")
4 không gọi
(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
3,
class Parent(object):
    def __init__(self):
        super(Parent, self).__init__()
        print("parent")

class Left(Parent):
    def __init__(self):
        super(Left, self).__init__()
        print("left")

class Right(Parent):
    def __init__(self):
        super(Right, self).__init__()
        print("right")

class Child(Left, Right):
    def __init__(self):
        super(Child, self).__init__()
        print("child")
5 vẫn bị bỏ qua:

Ở đây,

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
8 đầu ra:

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
0

child
left
right

(__main__.Child, __main__.Left, __main__.Right, __main__.Parent, object)
1