2009-12-24 38 views
5

Trong python 2.x, siêu chấp nhận các trường hợp sauTại sao python super không chỉ chấp nhận cá thể?

class super(object) 
| super(type) -> unbound super object 
| super(type, obj) -> bound super object; requires isinstance(obj, type) 
| super(type, type2) -> bound super object; requires issubclass(type2, type) 
| Typical use to call a cooperative superclass method: 

như xa như tôi thấy, siêu là một lớp, gói các loại và (cuối cùng) các trường hợp để giải quyết các lớp cha của một lớp.

tôi khá bối rối bởi một vài điều:

  • tại sao đó cũng là không super(instance), với việc sử dụng điển hình ví dụ super(self).__init__(). Về mặt kỹ thuật, bạn có thể lấy kiểu của một đối tượng từ chính đối tượng đó, vì vậy chiến lược hiện tại super(ClassType, self).__init__() là loại dự phòng. Tôi cho rằng các vấn đề tương thích với các lớp kiểu cũ hoặc nhiều thừa kế, nhưng tôi muốn nghe ý kiến ​​của bạn.
  • tại sao, mặt khác, python 3 sẽ chấp nhận (xem Understanding Python super() with __init__() methods) super().__init__()? Tôi thấy loại ma thuật trong điều này, vi phạm rõ ràng là tốt hơn so với Zen tiềm ẩn. Tôi đã thấy thích hợp hơn self.super().__init__().

Trả lời

6

super(ClassType, self).__init__()không dư thừa trong một chương trình thừa kế nhiều hợp tác xã - ClassType không nhất thiết phải là loại self, nhưng các lớp từ mà bạn muốn thực hiện cuộc gọi hợp tác để __init__.

Trong hệ thống phân cấp lớp C inherits B inherits A, trong C.__init__ bạn muốn gọi superclass 'init từ góc nhìn C's và bạn gọi B.__init__; sau đó trong B.__init__, bạn phải vượt qua loại lớp B đến siêu - vì bạn muốn giải quyết các lớp siêu hạng gọi là B (hay đúng hơn, tiếp theo trong mro sau B của lớp C).

class A (object): 
    def __init__(self): 
    pass 

class B (A): 
    def __init__(self): 
    super(B, self).__init__() 

class C (B): 
    def __init__(self): 
    super(C, self).__init__() 

nếu bây giờ bạn nhanh chóng c = C(), bạn thấy rằng kiểu lớp là không dư thừa - super(self).__init__() bên B.__init__ sẽ không thực sự làm việc! Những gì bạn làm là bạn tự xác định trong lớp nào phương thức gọi super là (một phương thức này được giải quyết trong siêu của Python 3 bởi một biến ẩn trỏ đến lớp của phương thức).

Hai liên kết với các ví dụ của siêu và đa kế thừa:

+0

Tôi đoán bạn có nghĩa là lớp B (A): và lớp C (B): –

+0

Tuy nhiên, bạn đã đúng. Nó sẽ không bao giờ có thể gọi A .__ init __() từ B, bởi vì trong phương pháp B .__ init __() tự sẽ thuộc loại C, có siêu trực tiếp là B, không A. Vì vậy, B .__ init __() sẽ được gọi lại. –

+0

ah bạn đúng về lỗi đánh máy, cảm ơn! Và điều này thậm chí còn phức tạp hơn trong nhiều kế hoạch thừa kế, tôi nghĩ rằng tôi có thể tìm thấy một liên kết về điều đó. – u0b34a0f6ae

3

Tôi không thể cung cấp câu trả lời cụ thể, nhưng bạn đã đọc PEP xung quanh siêu từ khóa chưa? Tôi đã làm một tìm kiếm google nhanh chóng và nó đã đưa ra PEP 367 và PEP 3135.

http://www.python.org/dev/peps/pep-0367/

http://www.python.org/dev/peps/pep-3135/#numbering-note

Không giống như bất kỳ ngôn ngữ khác mà tôi biết, hầu hết thời gian bạn có thể tìm thấy câu trả lời cho Python quirks trong PEP cùng với các tuyên bố hợp lý và vị trí rõ ràng.

Cập nhật:

Sau khi đọc qua 3135, email liên quan trong Mailing Python và ngôn ngữ tham khảo nó loại có ý nghĩa tại sao nó là cách nó là dành cho Python 2 vs Python 3.

http://docs.python.org/library/functions.html?highlight=super#super

Tôi nghĩ rằng siêu được triển khai rõ ràng/dư thừa chỉ ở bên an toàn và giữ logic liên quan càng đơn giản càng tốt (không có đường hoặc logic sâu để tìm cha mẹ). Vì siêu là một hàm dựng sẵn, nó phải suy ra sự trả về chính xác từ những gì được cung cấp mà không cần thêm sự phức tạp hơn vào cách các đối tượng Python được cấu trúc.

PEP 3135 thay đổi mọi thứ vì nó trình bày và giành được đối số cho cách tiếp cận DRY'er đến siêu.

+0

Tôi đồng ý, nhưng tôi đang cố gắng để có được một câu trả lời cho _while_ câu hỏi đồng thời tăng thông tin stackoverflow. –

+0

@Stefano Ngay lập tức sau khi tôi thực hiện bài đăng gốc của mình, tôi bắt đầu suy nghĩ cùng một điều. – David

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