CodeGym /Các khóa học /Python SELF VI /Thứ tự giải quyết phương thức (MRO)

Thứ tự giải quyết phương thức (MRO)

Python SELF VI
Mức độ , Bài học
Có sẵn

11.1 Thứ tự giải quyết phương thức

Thứ tự giải quyết phương thức (Method Resolution Order, MRO) xác định thứ tự mà Python tìm kiếm các phương thức và thuộc tính trong hệ thống phân cấp lớp. Điều này đặc biệt quan trọng khi làm việc với kế thừa đa lớp, khi một lớp có thể kế thừa các thuộc tính và phương thức từ nhiều lớp cha.

Nói một cách đơn giản, có một thứ tự cố định nghiêm ngặt (hoặc, đúng hơn, một thuật toán), theo đó Python đi qua cây kế thừa của các lớp. Thuật toán này đảm bảo một thứ tự tìm kiếm phương thức chính xác, có thể được mô tả như sau:

Thuật toán C3-linearization

Thuật toán C3-linearization xác định MRO thông qua việc kết hợp:

  • Bản thân lớp.
  • Danh sách các lớp cha theo thứ tự liệt kê của chúng.
  • MRO của các lớp cha theo thứ tự tương tự.

Quy tắc của thuật toán C3-linearization

  • Duy trì thứ tự phương thức địa phương: nếu lớp A được liệt kê trước lớp B, tất cả các phương thức của lớp A phải được xem xét trước các phương thức của lớp B.
  • Duy trì thứ tự trong các lớp cha: nếu lớp A là lớp cha của lớp B, tất cả các phương thức của lớp A phải được xem xét trước các phương thức của lớp B.
  • Xem xét thứ tự kế thừa: nếu lớp C là lớp cha của hai hoặc nhiều lớp, thứ tự phương thức của lớp C phải được duy trì trong MRO của tất cả các lớp này.

Các bước của thuật toán:

Bước 1. Bắt đầu với lớp hiện tại:

Luôn bắt đầu với lớp hiện tại nơi mà phương thức được gọi.

Bước 2. Thêm các lớp cơ bản theo thứ tự liệt kê:

Sau lớp hiện tại, kiểm tra các lớp cơ bản theo thứ tự mà chúng được liệt kê khi kế thừa.

Bước 3. Duyệt qua các lớp cha:

Tìm kiếm các thuộc tính và phương thức ở đó.

Bước 4. Kết hợp MRO của các lớp cha:

Nếu một lớp cơ bản được kế thừa qua nhiều đường dẫn, nó chỉ được kiểm tra một lần và theo đúng thứ tự (tất cả các lần khác nó sẽ bị bỏ qua).

Đối với những ai đã quen thuộc với chủ đề "Thuật toán và cấu trúc dữ liệu", đây là tìm kiếm theo chiều sâu chứ không phải tìm kiếm theo chiều rộng.

11.2 Kiểm tra MRO

Trong Python, bạn có thể kiểm tra thứ tự tìm kiếm phương thức và thuộc tính của lớp, bằng cách sử dụng thuộc tính __mro__ hoặc hàm mro().

Ví dụ:


class A:
    def method(self):
        print("A")
        
class B(A):
    def method(self):
        print("B")
        
class C(A):
    def method(self):
        print("C")
        
class D(B, C):
    def method(self):
        print("D")
        

# Kiểm tra MRO
print(D.__mro__)
        

Kết quả sẽ là:


(<class '__main__.D'>, 
<class '__main__.B'>, 
<class '__main__.C'>,
<class '__main__.A'>,
<class 'object'>)
        

Điều này cho thấy thứ tự mà Python sẽ tìm kiếm phương thức và thuộc tính:

  • D: Python trước hết kiểm tra phương thức trong lớp D.
  • B: Sau đó Python kiểm tra phương thức trong lớp B (lớp cha đầu tiên).
  • C: Nếu phương thức không được tìm thấy trong lớp B, Python kiểm tra phương thức trong lớp C (lớp cha thứ hai).
  • A: Nếu phương thức không được tìm thấy trong các lớp BC, Python kiểm tra phương thức trong lớp A.
  • object: Cuối cùng, Python kiểm tra phương thức trong lớp cơ bản object.

11.3 Sử dụng super() với MRO

Hàm super() tuân theo MRO để gọi các phương thức của lớp cha theo đúng thứ tự. Hãy xem một ví dụ về việc sử dụng super():

class A:
    def method(self):
        print("A")
        super().method()
        
class B(A):
    def method(self):
        print("B")
        super().method()
        
class C(A):
    def method(self):
        print("C")
        super().method()
        
class D(B, C):
    def method(self):
        print("D")
        super().method()
        
        
d = D()
d.method()
        

Kết quả sẽ là:


D
B
C
A
        

Thứ tự duyệt qua (MRO)

1. Gọi phương thức method của lớp D:

  • Python trước hết kiểm tra phương thức trong lớp D và tìm thấy nó ở đó.
  • Phương thức D.method() được thực thi và in ra "D".
  • Sau đó super().method() được gọi, tuân theo MRO để gọi phương thức tiếp theo.

2. Gọi phương thức method của lớp B:

  • Theo MRO, lớp tiếp theo sau DB.
  • Phương thức B.method() được thực thi và in ra "B".
  • Sau đó super().method() được gọi, tuân theo MRO để gọi phương thức tiếp theo.

3. Gọi phương thức method của lớp C:

  • Lớp tiếp theo trong MRO sau BC.
  • Phương thức C.method() được thực thi và in ra "C".
  • Sau đó super().method() được gọi, tuân theo MRO để gọi phương thức tiếp theo.

4. Gọi phương thức method của lớp A:

  • Lớp tiếp theo trong MRO sau CA.
  • Phương thức A.method() được thực thi và in ra "A".
  • Sau đó super().method() được gọi, nhưng vì A không có các phương thức method nào khác (ngoài object), cuộc gọi kết thúc mà không có hành động nào thêm.
1
Опрос
Kế thừa,  16 уровень,  5 лекция
недоступен
Kế thừa
Kế thừa
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION