2013-04-09 6 views
14

Xét:Python siêu() thừa kế và lập luận cần thiết

class Parent(object): 

    def altered(self): 
     print "PARENT altered()" 

class Child(Parent): 

    def altered(self): 
     print "CHILD, BEFORE PARENT altered()" 
     super(Child, self).altered() # what are the arguments needed? Why Child and self? 
     print "CHILD, AFTER PARENT altered()" 

Trong Python 2.7, Tại sao phải Child được thông qua như là một cuộc tranh cãi với super() cuộc gọi? Những gì phức tạp chính xác của việc sử dụng siêu thay vì chỉ để cho nó hoạt động.

+7

Theo như tôi biết, nó phải làm với MRO. Nhưng tôi không đủ giỏi để giải thích nó cho một câu trả lời "thực sự". Có lẽ điều này sẽ giúp: http://rhettinger.wordpress.com/2011/05/26/super-considered-super/ Lưu ý rằng các đối số không cần thiết nữa trong Python 3. –

+0

Vì vậy, đối số đầu tiên là "Con" là cho lớp bạn đang ở và không phải lớp bạn muốn kế thừa từ khi Phụ huynh là cơ sở? Một cái gì đó như thế tôi cho là vậy. Cũng cảm ơn cho đọc và tôi đang sử dụng Python 2,7 để được rõ ràng. Tôi sẽ tiếp tục đọc về siêu() –

Trả lời

18

super tìm ra đây là lớp tiếp theo trong Thứ tự phân giải phương pháp. Hai đối số bạn truyền vào là những gì cho phép nó tìm ra điều đó - self cho nó toàn bộ MRO thông qua một thuộc tính; lớp hiện tại cho biết bạn đang ở đâu dọc theo MRO ngay bây giờ. Vì vậy, những gì siêu được thực sự làm về cơ bản là:

def super(cls, inst): 
    mro = inst.__class__.mro() # Always the most derived class 
    return mro[mro.index(cls) + 1] 

Lý do nó là lớp hiện tại chứ không phải là lớp cơ sở được vì toàn bộ điểm của việc có siêu là phải có một chức năng mà làm việc ra những gì mà lớp cơ sở là khá có thể gây ra vấn đề nếu tên của lớp cơ sở thay đổi, nếu bạn không biết chính xác lớp cha được gọi là gì (hãy suy nghĩ về các chức năng của nhà máy như namedtuple để tạo ra một lớp mới), và đặc biệt trong các tình huống đa thừa kế (trong đó lớp tiếp theo trong MRO có thể không phải là một trong các cơ sở của lớp hiện tại).

+0

Lý do là lớp hiện tại thay vì lớp cơ sở là vì toàn bộ điểm có siêu là có một hàm làm việc ra lớp cơ sở nào hơn là phải tham chiếu đến nó một cách rõ ràng . Tôi nghĩ rằng dòng bạn nói tóm tắt nó lên độc đáo. Tôi sẽ nhìn vào MRO và nhận ra rằng đây chỉ là một khía cạnh của python 2.x vì python 3 không yêu cầu các đối số này. Cảm ơn bạn. –

+3

@klandshome Python 3 siêu hoạt động chính xác theo cùng một cách - nó chỉ có một số augmentations thú vị để có thể tìm ra các đối số cho chính nó trong hầu hết trường hợp (bằng cách kiểm tra ngăn xếp cuộc gọi) thay vì bạn phải vượt qua chúng. – lvc

+1

Hmm. Thông tin tuyệt vời. Ngăn xếp cuộc gọi. Tôi học được rất nhiều. Cảm ơn bạn. –