2015-01-14 14 views
9

Tài liệu Python 2 nói rằng super() chức năng "trả về một đối tượng proxy ủy nhiệm các cuộc gọi phương thức cho một lớp cha hoặc anh chị em của loại."Một lớp anh chị em trong Python là gì?

Những câu hỏi:

  1. một lớp anh chị em bằng Python là gì?
  2. Làm thế nào để bạn ủy thác một cuộc gọi phương thức cho một lớp anh chị em?

Giả định của tôi là một anh chị em cho một lớp nhất định là một lớp kế thừa từ cùng một cấp độ gốc. Tôi đã soạn thảo mã sau đây để xem cách gọi phương thức có thể được giao cho anh chị em, nhưng nó không hoạt động. Tôi phải làm gì hoặc hiểu sai?

class ClassA(object): 
    def MethodA(self): 
     print "MethodA of ClassA" 

class ClassB(ClassA): 
    def MethodB(self): 
     print "MethodB of ClassB" 

class ClassC(ClassA): 
    def MethodA(self): 
     super(ClassC, self).MethodA() 

    def MethodB(self): 
     super(ClassC, self).MethodB() 

if __name__ == '__main__': 
    ClassC().MethodA() # Works as expected 

    # Fail while trying to delegate method to a sibling. 
    ClassC().MethodB() # AttirbuteError: 'super' object has no attribute 'MethodB' 
+0

Tôi không có thời gian để viết câu trả lời đầy đủ, nhưng tôi nghĩ rằng các tài liệu đang đề cập đến nhiều thừa kế. Nếu lớp C kế thừa từ cả A và B thì bạn có thể xem xét A và B là 'anh chị em' theo một nghĩa nào đó. 'super()' các cuộc gọi trong cơ thể của A trên một thể hiện của C sẽ đại biểu cho B. Xem [câu hỏi này] (http://stackoverflow.com/questions/3277367/how-does-pythons-super-work-with -multiple-inheritance) cho thấp xuống. –

+1

Câu trả lời được chấp nhận cho câu hỏi này ở đây giải thích chi tiết về cách 'super()' thực sự có thể gọi cha mẹ nhưng cũng là các lớp anh chị em: http://stackoverflow.com/questions/5033903/python-super-method-and-calling-alternatives –

+0

@SimeonVisser, tôi đã thấy câu hỏi đó, thậm chí còn đóng vai chính nó. Nó không đưa ra câu trả lời rõ ràng cho lớp anh chị em là gì. Câu hỏi này liên quan đến câu hỏi đó, nhưng rõ ràng không phải là một bản sao. – golem

Trả lời

5

Sau khi một số nghiên cứu thêm và đọc Python’s super() considered super! bài viết tôi đã đến kết luận sau:

  1. Một lớp anh chị em là những gì tôi đã suy nghĩ nó là gì. Nó là một lớp kế thừa từ cùng một bậc cha mẹ. Đó là định nghĩa của tài liệu Python đã ném tôi ra khỏi khóa học. Dường như khi tài liệu Python cho biết các cuộc gọi phương thức của đại biểu đến một lớp cha hoặc anh chị em thì có nghĩa là đối với cha mẹ hoặc cha mẹ của cha mẹ cũng là lớp cơ sở của một đứa trẻ nhất định. Đó là một sự thừa kế kim cương phải diễn ra.

  2. super() chức năng đại biểu một phương pháp gọi đến lớp anh chị em một cha mẹ tự động dựa trên MRO (phương pháp để giải quyết).

Dưới đây là một trường hợp thú vị tôi tìm thấy trong khi thử nghiệm với super() chức năng:

class Class0(object): 
    def MethodA(self): 
     print("MethodA of Class0") 

class ClassA(Class0): 
    def MethodA(self): 
     super(ClassA, self).MethodA() 
     print("MethodA of ClassA") 

class ClassB(Class0): 
    def MethodA(self): 
     print("MethodA of ClassB") 

class ClassC(ClassA, ClassB): 
    def MethodA(self): 
     super(ClassC, self).MethodA() 

if __name__ == '__main__': 
    ClassC().MethodA() 

Mã này sẽ in

MethodA of ClassB 
MethodA of ClassA 

Nếu bạn là tôi tự hỏi tại sao MethodA của Class0 không bao giờ in, đây là lời giải thích khi tôi hiểu nó. MRO của ClassC được in với print(ClassC.__mro__)

(<class '__main__.ClassC'>, <class '__main__.ClassA'>, <class '__main__.ClassB'>, <class '__main__.Class0'>, <class 'object'>).

Bây giờ nếu bạn làm theo MRO, hàm super() của MethodA() của ClassC sẽ gọi MethodA() của ClassA, trước khi in sẽ gọi MethodA() của classB (vì nó tiếp theo trong MRO). Và MethodA() của ClassB lần lượt sẽ chỉ in và thoát vì nó không sử dụng hàm super() để ủy quyền cho phương thức gọi thêm chuỗi MRO.

0

Một anh chị em là một lớp học có cùng cha hoặc mẹ, như bạn nghi ngờ. Trường hợp bạn đang thiếu là super có thể gọi một phương pháp anh chị em nếu lớp này tự nó đã được thừa hưởng từ nhân:

class A(object): 
    def something(self): 
    print("A") 
class B(A): 
    def something(self): 
    print("B") 
class C(A): 
    def something(self): 
    print("C, about to call super()") 
    super(C, self).something() 
class D(C, B): 
    def something(self): 
    super(D, self).something() 

>>> D().something() 
C, about to call super() 
B 

Trong C, chúng tôi gọi super(), nhưng chúng tôi đã nhận B - mà là một anh chị em, không phải là cha/mẹ và không phải là là cha mẹ của anh chị em ruột, nhưng là anh chị em trực tiếp thực tế của C.

+0

Cảm ơn, tôi đã đi đến cùng một kết luận. Tôi nghĩ rằng định nghĩa chính xác hơn sẽ là * anh chị em của cha mẹ mà cũng là một lớp cơ sở của một đứa trẻ nhất định * - định nghĩa tôi sử dụng trong câu trả lời của riêng tôi. – golem

+0

Không, đó không phải là định nghĩa chính xác. 'B' không phải là 'anh chị em * của cha/mẹ * của' C'. Đó là một * anh chị em * của 'C'. – lmm

+0

B là cha mẹ đầu tiên, C là cha mẹ thứ hai. B và C là anh chị em ruột. Trong * anh chị em của cha mẹ mà cũng là một lớp cơ sở của một đứa trẻ * thay thế và bạn sẽ nhận được: anh chị em của B cũng là một lớp cơ sở của D. Đó là C =). – golem

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