Câu trả lời:
Dõi theo...:
>>> class A(object): pass
...
>>> A.__mro__
(<class '__main__.A'>, <type 'object'>)
>>> class B(A): pass
...
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
>>> class C(A): pass
...
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
>>>
Chừng nào chúng ta còn có sự kế thừa duy nhất, __mro__
chỉ là bộ ba: lớp, cơ sở của nó, cơ sở của nó, v.v.object
(tất nhiên chỉ hoạt động cho các lớp kiểu mới).
Bây giờ, với nhiều kế thừa ...:
>>> class D(B, C): pass
...
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
... bạn cũng có được sự đảm bảo rằng, trong __mro__
, không có lớp nào được sao chép và không có lớp nào xuất hiện sau tổ tiên của nó, lưu các lớp đầu tiên nhập vào cùng một mức độ thừa kế (như B và C trong ví dụ này) __mro__
trái sang phải
Mọi thuộc tính bạn nhận được trên một thể hiện của một lớp, không chỉ các phương thức, được tìm kiếm một cách khái niệm dọc theo __mro__
, vì vậy, nếu có nhiều hơn một lớp trong số tổ tiên định nghĩa tên đó, thì điều này sẽ cho bạn biết nơi thuộc tính sẽ được tìm thấy - trong lớp đầu tiên trong cái __mro__
đó định nghĩa cái tên đó
mro
có thể được tùy chỉnh bởi một siêu dữ liệu, được gọi một lần khi khởi tạo lớp và kết quả được lưu trữ trong __mro__
- xem docs.python.org/l Library / .
mro()
là viết tắt của Phương thức giải quyết lệnh. Nó trả về một danh sách các loại mà lớp có nguồn gốc, theo thứ tự chúng được tìm kiếm cho các phương thức.
mro () hoặc __mro__ chỉ hoạt động trên các lớp kiểu mới. Trong python 3, chúng hoạt động mà không có vấn đề gì. Nhưng trong python 2 các lớp đó cần phải kế thừa từ object
.
Điều này có lẽ sẽ hiển thị thứ tự của độ phân giải.
class A(object):
def dothis(self):
print('I am from A class')
class B(A):
pass
class C(object):
def dothis(self):
print('I am from C class')
class D(B, C):
pass
d_instance= D()
d_instance.dothis()
print(D.mro())
và phản hồi sẽ là
I am from A class
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
Quy tắc là chiều sâu trước tiên, trong trường hợp này có nghĩa là D, B, A, C.
Python thường sử dụng thứ tự độ sâu đầu tiên khi tìm kiếm các lớp kế thừa, nhưng khi hai lớp kế thừa từ cùng một lớp, Python sẽ loại bỏ đề cập đầu tiên của lớp đó khỏi mro.
Thứ tự giải quyết sẽ khác nhau trong thừa kế kim cương.
class A(object):
def dothis(self):
print('I am from A class')
class B1(A):
def dothis(self):
print('I am from B1 class')
# pass
class B2(object):
def dothis(self):
print('I am from B2 class')
# pass
class B3(A):
def dothis(self):
print('I am from B3 class')
# Diamond inheritance
class D1(B1, B3):
pass
class D2(B1, B2):
pass
d1_instance = D1()
d1_instance.dothis()
# I am from B1 class
print(D1.__mro__)
# (<class '__main__.D1'>, <class '__main__.B1'>, <class '__main__.B3'>, <class '__main__.A'>, <class 'object'>)
d2_instance = D2()
d2_instance.dothis()
# I am from B1 class
print(D2.__mro__)
# (<class '__main__.D2'>, <class '__main__.B1'>, <class '__main__.A'>, <class '__main__.B2'>, <class 'object'>)
class B3
nhưng trong trường hợp thứ hai thì nó lại đến class A
sauclass B1