Hướng dẫn real python multiple inheritance - đa kế thừa python thực

Python hỗ trợ kế thừa từ nhiều lớp. Trong bài học này, bạn sẽ thấy:inheritance from multiple classes. In this lesson, you’ll see:

  • Cách thức hoạt động của nhiều kế thừa
  • Cách sử dụng super() để gọi các phương thức được kế thừa từ nhiều phụ huynh
  • Sự phức tạp nào xuất phát từ nhiều kế thừa
  • Cách viết mixin, là cách sử dụng phổ biến của nhiều kế thừa

Một lớp học có thể thừa hưởng từ nhiều phụ huynh. Ví dụ: bạn có thể xây dựng một lớp đại diện cho hình dạng 3D bằng cách kế thừa từ hai hình 2D:

class RightPyramid(Triangle, Square):
    def __init__(self, base, slant_height):
        self.base = base
        self.slant_height = slant_height

    def what_am_i(self):
        return 'RightPyramid'

Thứ tự phân giải phương pháp (MRO) xác định nơi Python tìm kiếm một phương thức khi có hệ thống phân cấp các lớp. Sử dụng super() truy cập lớp tiếp theo trong MRO:Method Resolution Order (MRO) determines where Python looks for a method when there is a hierarchy of classes. Using super() accesses the next class in the MRO:

class A:
    def __init__(self):
        print('A')
        super().__init__()

class B(A):
    def __init__(self):
        print('B')
        super().__init__()

class X:
    def __init__(self):
        print('X')
        super().__init__()

class Forward(B, X):
    def __init__(self):
        print('Forward')
        super().__init__()

class Backward(X, B):
    def __init__(self):
        print('Backward')
        super().__init__()

Nếu bạn kết hợp tính năng MRO và **kwargs để chỉ định các cặp giá trị tên trong quá trình xây dựng, bạn có thể viết mã chuyển các tham số cho các lớp cha ngay cả khi chúng có tên khác nhau:**kwargs feature for specifying name-value pairs during construction, you can write code that passes parameters to parent classes even if they have different names:

class Rectangle:
    def __init__(self, length, width, **kwargs):
        self.length = length
        self.width = width
        super().__init__(**kwargs)

    def area(self):
        return self.length * self.width

    def perimeter(self):
        return 2 * self.length + 2 * self.width

class Square(Rectangle):
    def __init__(self, length, **kwargs):
        super().__init__(length=length, width=length, **kwargs)

class Triangle:
    def __init__(self, base, height, **kwargs):
        self.base = base
        self.height = height
        super().__init__(**kwargs)

    def tri_area(self):
        return 0.5 * self.base * self.height

class RightPyramid(Square, Triangle):
    def __init__(self, base, slant_height, **kwargs):
        self.base = base
        self.slant_height = slant_height
        kwargs["height"] = slant_height
        kwargs["length"] = base
        super().__init__(base=base, **kwargs)

    def area(self):
        base_area = super().area()
        perimeter = super().perimeter()
        return 0.5 * perimeter * self.slant_height + base_area

    def area_2(self):
        base_area = super().area()
        triangle_area = super().tri_area()
        return triangle_area * 4 + base_area

Nhiều kế thừa có thể trở nên khó khăn nhanh chóng. Một trường hợp sử dụng đơn giản là phổ biến trong trường là viết một mixin. Một mixin là một lớp không quan tâm đến vị trí của nó trong hệ thống phân cấp, nhưng chỉ cung cấp một hoặc nhiều phương pháp tiện lợi:mixin. A mixin is a class that doesn’t care about its position in the hierarchy, but just provides one or more convenience methods:

class SurfaceAreaMixin:
    def surface_area(self):
        surface_area = 0
        for surface in self.surfaces:
            surface_area += surface.area(self)

        return surface_area

class Cube(Square, SurfaceAreaMixin):
    def __init__(self, length):
        super().__init__(length)
        self.surfaces = [Square, Square, Square, Square, Square, Square]

class RightPyramid(Square, Triangle, SurfaceAreaMixin):
    def __init__(self, base, slant_height):
        self.base = base
        self.slant_height = slant_height
        self.height = slant_height
        self.length = base
        self.width = base

        self.surfaces = [Square, Triangle, Triangle, Triangle, Triangle]

Đây là những gì bạn nhận được:

>>>

>>> cube = Cube(3)
>>> cube.surface_area()
54