2012-04-05 36 views
6

Trước hết, tôi phải xin lỗi vì không có tiêu đề tốt hơn. Hãy thay đổi nó nếu bạn thấy thích hợp hơn.thừa kế kim cương python và sử dụng super() trong bố mẹ của lớp dẫn xuất

Về cơ bản, tôi đã bị lỗi bởi hành vi đa thừa kế của Python. Trong số previous SO question của mình, tôi được hướng dẫn đọc Python's C3 MRO. Điều đó thực sự giúp tôi hiểu rõ hơn về đa thừa kế trong Python. Ngay khi tôi nghĩ rằng tôi đã nắm bắt được nó, tôi va vào kịch bản sau đây, mà tôi dường như không thể hiểu được.

class UltimateBase(object): 
    def check(self): 
     print 'base check' 

class AMixin1(UltimateBase): 
    def check(self): 
     print 'check A' 

class BMixin1(UltimateBase): 
    def check(self): 
     print 'check B' 

class CMixin1(UltimateBase): 
    def check(self): 
     print 'check C' 

class AMixin2(UltimateBase): 
    def check(self): 
     print 'check A' 
     return super(AMixin2, self).check() 

class BMixin2(UltimateBase): 
    def check(self): 
     print 'check B' 
     return super(BMixin2, self).check() 

class CMixin2(UltimateBase): 
    def check(self): 
     print 'check C' 
     return super(CMixin2, self).check() 

class MyView1(AMixin1, BMixin1, CMixin1): 
    pass 

class MyView2(AMixin2, BMixin2, CMixin2): 
    pass 

class MyView3(AMixin1, BMixin2, CMixin2): 
    pass 

class MyView4(AMixin2, BMixin1, CMixin2): 
    pass 

class MyView5(AMixin2, BMixin2, CMixin1): 
    pass 

class MyView6(AMixin1, BMixin1, CMixin2): 
    pass 

class MyView7(AMixin1, BMixin2, CMixin1): 
    pass 

class MyView8(AMixin2, BMixin1, CMixin1): 
    pass 

myview1 = MyView1() 
myview2 = MyView2() 
myview3 = MyView3() 
myview4 = MyView4() 
myview5 = MyView5() 
myview6 = MyView6() 
myview7 = MyView7() 
myview8 = MyView8() 

myview1.check() 
print '------------------------' 
myview2.check() 
print '------------------------' 
myview3.check() 
print '------------------------' 
myview4.check() 
print '------------------------' 
myview5.check() 
print '------------------------' 
myview6.check() 
print '------------------------' 
myview7.check() 
print '------------------------' 
myview8.check() 
print '------------------------' 

Đầu ra:

check A 
------------------------ 
check A 
check B 
check C 
base check 
------------------------ 
check A 
------------------------ 
check A 
check B 
------------------------ 
check A 
check B 
check C 
------------------------ 
check A 
------------------------ 
check A 
------------------------ 
check A 
check B 
------------------------ 

tôi có thể truy ra một mô hình dựa trên quan sát các kết quả đầu ra, nhưng nó làm tôi phát cáu không hiểu lý do đằng sau kết quả này.

tôi có thắc mắc như thế nào, ví dụ, tại sao myview2.check() trở

check A 
check B 
check C 
base check 

không

check A 
base check 

Dường như với tôi rằng tôi thiếu một mảnh quan trọng về đa kế thừa. Xin vui lòng điền vào khoảng trống cho tôi.

Trả lời

4

Khi bạn gọi myview2.check(), nó truyền qua anh chị em rồi gọi lớp cơ sở. Bất cứ khi nào một trong những lượt truy cập đó truy cập AMixin1, BMixin1 hoặc CMixin1 thì dừng lại bởi vì các lớp đó không gọi là super(..., self).check().

Như Benn chỉ ra, điều này được mô tả trong official Python documentation. Và nếu bạn nghĩ về nó, nó khá nhiều đã phải làm việc theo cách này. Các lớp con sẽ giả sử phương thức lớp cơ sở không được gọi trước khi lớp con gọi super(). Nếu nó là (hoặc, tệ hơn, nếu nó phụ thuộc vào thứ tự anh chị em của nó được liệt kê), nó làm cho mọi thứ rất khó để giải quyết.

+0

Cảm ơn Chris. Điều này khá trực quan. Từ giao diện kết quả, 'check()' của tổ tiên chung không được gọi trừ khi tất cả các bậc cha mẹ gọi là 'super()'. Có văn học nào nói về điều này không? – tamakisquare

+1

Thay vì thêm một câu trả lời khác mà nói chủ yếu là giống nhau, tôi sẽ chỉ liên kết tài liệu của 'super()', mà làm phép thuật trong trường hợp này: [Tài liệu Python chính thức] (http: //docs.python. org/library/functions.html? highlight = super # super). Điều quan trọng là nó sẽ gọi cha mẹ _or siblings_ của 'loại' cho hợp tác đa thừa kế. – Benn

+0

@Benn - Đó chính là mảnh cuối cùng tôi cần cho vấn đề của mình. Cảm ơn bạn rất nhiều. – tamakisquare

1

Cố gắng làm cho đầu của tôi tròn cùng một câu hỏi. tôi thấy đoạn mã sau giúp đơn giản hóa vấn đề: (. Về cơ bản, khi tất cả các super s đã bị ảnh hưởng cho một lớp học, lớp học mà được gọi là)

class A: 
    def f(self): 
    print("............A: the common base of B and C") 

class B(A): 
    def f(self): 
    print("........B: the left base of D") 
    super().f() 

class C(A): 
    def f(self): 
    print("........C: the right base of D") 
    super().f() 

class D(B,C): 
    def f(self): 
    print("....D: the top class") 
    super().f() 

d = D() 

d.f() 

Output:

....D: the top class 
........B: the left base of D 
........C: the right base of D 
............A: the common base of B and C 

Try Online

Các vấn đề liên quan