2014-11-15 10 views
6

(Tôi không thể tìm thấy một tài liệu tham khảo bất cứ nơi nào về vấn đề này sau khi một số Googling.)Khi nào cần gọi hàm super() .__ init __() của Python?

Kịch bản có thể được chứng minh rõ ràng với mẫu mã ngắn này:

class X: 
    def __init__(self, stuff): 
     self.__stuff = stuff 

class Y(X): 
    def __init__(self, stuff): 
     # Is it safe to execute statements before calling super.__init__()? 
     new_stuff = self.call_another_method(stuff) 
     super(Y, self).__init__(new_stuff) 

Sử dụng CPython 3.x, ở trên mẫu mã hoạt động - giả sử call_another_method() tồn tại. Kiểu mã hóa này nói chung là an toàn, nhưng cau mày hay được coi là unPythonic? Tôi không thể tìm thấy lời khuyên về vấn đề này.

Tại sao tôi quan tâm?

Nền của tôi xuất phát từ nhiều ngôn ngữ lập trình hướng đối tượng truyền thống như C++, C# và Java, nơi "siêu" phải được gọi đúng như câu lệnh đầu tiên trong một hàm tạo lớp con - bỏ qua trường hợp không đối số.

Nếu nó quan trọng, tôi còn trẻ Pythoneer: 3+, xin vui lòng.

+1

IIRC, trong Python 3.x, bạn không cần phải gọi 'super (ClassName, self)' nữa, 'super()' trên chính nó hoạt động tốt. –

+0

Về điều duy nhất 'super' trong Java và Python có điểm chung là tên. Java 'super' là một từ khóa tham chiếu đến lớp cơ sở (duy nhất); Python 'super' là một hàm dựng sẵn, sử dụng các đối số của nó, trả về một đối tượng phục vụ như một proxy cho một số lớp trong thứ tự phân giải phương thức của đối tượng. – chepner

+0

@ChinmayKanchi: Cảm ơn bạn đã biết mẹo. Tôi sẽ cập nhật mã của mình trong tương lai! – kevinarpe

Trả lời

9

Có, hoàn toàn an toàn khi gọi những thứ khác trước super(). Python không đặt hàng, và có rất nhiều trường hợp sử dụng cho việc này.

Lưu ý rằng super().__init__() gọi là chỉ là một biểu thức khác bằng Python, nó không phải là cú pháp xây dựng. Bạn cũng có thể sử dụng super() các phương thức bên ngoài, miễn là bạn vượt qua các đối số phù hợp.

Trong trường hợp của bạn, bạn có thể bỏ qua các loại và dụ đối số, Python 3 sẽ lấy những cho bạn khi super() được gọi là không có đối số, bởi vì bạn đang sử dụng nó trong một chức năng được xác định bên trong một lớp:

class Y(X): 
    def __init__(self, stuff): 
     new_stuff = self.call_another_method(stuff) 
     # super(Y, self) is implicit here: 
     super().__init__(new_stuff) 
+1

Lưu ý rằng khi trong C++ bạn không gọi hàm constuctor của cơ sở một cách rõ ràng, hàm tạo mặc định của nó sẽ được gọi ngầm định. Trong Python, nếu bạn không gọi nó là hoàn toàn, nó sẽ không được gọi. "_Explicit tốt hơn là ngầm định._" – GingerPlusPlus

+0

@GingerPlusPlus: Ja. Tương tự cho C# và Java (và nhiều thứ khác). – kevinarpe

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