2013-12-08 22 views
10

Vì vậy, tôi có một tình huống như thế này.Phương thức cha mẹ gọi Python Nhiều thừa kế

class A(object): 
    def foo(self, call_from): 
     print "foo from A, call from %s" % call_from 


class B(object): 
    def foo(self, call_from): 
     print "foo from B, call from %s" % call_from 


class C(object): 
    def foo(self, call_from): 
     print "foo from C, call from %s" % call_from 


class D(A, B, C): 
    def foo(self): 
     print "foo from D" 
     super(D, self).foo("D") 

d = D() 
d.foo() 

Kết quả của mã là

foo from D 
foo from A, call from D 

Tôi muốn gọi tất cả các phương pháp phụ huynh, trong trường hợp này, phương pháp foo, từ D lớp mà không sử dụng siêu ở lớp cha mẹ như A. Tôi chỉ muốn gọi siêu từ lớp D. Lớp học A, BC giống như lớp mixin và tôi muốn gọi tất cả phương thức foo từ D. Làm thế nào tôi có thể đạt được điều này?

Trả lời

7

Bạn có thể sử dụng __bases__ như thế này

class D(A, B, C): 
    def foo(self): 
     print "foo from D" 
     for cls in D.__bases__: 
      cls().foo("D") 

Với sự thay đổi này, sản lượng sẽ

foo from D 
foo from A, call from D 
foo from B, call from D 
foo from C, call from D 
+0

Đây là một chút sơ sài ... Nếu bây giờ bạn có hai lớp mà cả hai đều kế thừa từ D và sau đó là một lớp khác thừa kế từ cả hai? Bây giờ 'foo' sẽ gọi 'A.foo' hai lần. – mgilson

+1

Hoặc điều gì xảy ra nếu 'B.foo' không tồn tại? Và cuối cùng, tôi nghĩ rằng nó nên là 'cls.foo (self)', không phải 'cls(). Foo()' – mgilson

+0

@mgilson Sau đó, chúng ta phải sử dụng 'mro'? Và đó không phải là phương pháp lớp, phải không? Vì vậy, tôi đã phải tạo ra các đối tượng để gọi cho họ. – thefourtheye

8

Thêm super() cuộc gọi trong các lớp khác ngoại trừ C. Vì MRO của D là

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

Bạn không cần cuộc gọi siêu trong C.

Code:

class A(object): 
    def foo(self, call_from): 
     print "foo from A, call from %s" % call_from 
     super(A,self).foo('A') 

class B(object): 
    def foo(self, call_from): 
     print "foo from B, call from %s" % call_from 
     super(B, self).foo('B') 


class C(object): 
    def foo(self, call_from): 
     print "foo from C, call from %s" % call_from 

class D(A, B, C): 
    def foo(self): 
     print "foo from D" 
     super(D, self).foo("D") 

d = D() 
d.foo() 

Output:

foo from D 
foo from A, call from D 
foo from B, call from A 
foo from C, call from B 
+0

Trong trường hợp bạn không hiểu mô tả của mình, tôi muốn gọi tất cả phương thức 'foo' mà không gọi siêu ở cấp độ gốc như' A' hoặc 'B' hoặc' C'. –

+1

@EdwinLunando - Tôi tin rằng đó không phải là cách nó diễn ra. Để siêu hoạt động bình thường, tất cả các lớp cần sử dụng nó. [xem phần trộn siêu phương pháp với các phương pháp không siêu] (https://fuhm.net/super-harmful/). – mgilson

+0

@EdwinLunando Sau đó lặp lại trên '__mro__', hoặc' __bases__' và gọi mỗi lớp một cách rõ ràng, nhưng sau đó bạn ** không thể sử dụng ** 'super' trong' D'. –

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