2011-06-30 26 views
6

Tôi đã tạo một đoạn mã nhỏ vì tôi vẫn đang cố gắng tìm ra các chi tiết cụ thể về cách sử dụng super(). Tại sao đoạn này chạy đến số TypeError này?Tôi có sử dụng super() chính xác không?

a = SecondClass() 
TypeError: __init__() takes exactly 2 arguments (1 given) 

Sau đó, chức năng SecondClass.meth() được cho là in chuỗi, nhưng tôi thiếu rõ ràng một điều gì đó mang tính khái niệm.

class FirstClass (object): 
    def __init__ (self, value): 
     self.value = value 
     print self.value 

class SecondClass (FirstClass): 
    def meth (self): 
     super (FirstClass,self).__init__(value = "I am a strange string") 

a = SecondClass() 
a.meth() 
+3

Gọi hàm tạo siêu lớp từ một phương thức lớp con là một ý tưởng ... * thú vị *. –

Trả lời

8

Đây không phải là bất cứ điều gì để làm với super. Bạn không xác định một số __init__ cho SecondClass một cách rõ ràng - nhưng, vì nó được kế thừa từ FirstClass, nó kế thừa 's __init__. Vì vậy, bạn không thể khởi tạo đối tượng mà không đi qua tham số value.

Chỉnh sửa OK. Điểm đầu tiên, như những người khác đã đề cập, là bạn phải luôn sử dụng lớp hiện tại trong siêu cuộc gọi của mình, không phải là siêu lớp - trong trường hợp này là super(SecondClass, self). Đó là bởi vì siêu có nghĩa là "có được cha mẹ của lớp x", vì vậy rõ ràng bạn có nghĩa là "có được cha mẹ của SecondClass" - đó là FirstClass.

Điểm thứ hai là bạn không nên gọi phương thức __init__ bên trong meth. __init__đã được gọi khi bạn khởi tạo đối tượng. Hoặc là lớp con của bạn định nghĩa phiên bản riêng của nó, có thể chọn có hay không gọi phương thức siêu riêng của nó; hoặc, như trong trường hợp này, nó không, trong trường hợp đó phiên bản của siêu lớp được gọi tự động.

Hãy để tôi lặp lại điều đó, bởi vì tôi nghi ngờ rằng đây là phần còn thiếu trong sự hiểu biết của bạn: toàn bộ điểm của phân lớp là bất cứ điều gì bạn không ghi đè cụ thể, dù sao cũng được thừa hưởng. superchỉ cho những trường hợp đó khi bạn muốn ghi đè điều gì đó, nhưng vẫn sử dụng logic từ siêu lớp cũng như.

Vì vậy, đây là một ví dụ ngớ ngẩn:

class FirstClass(object): 
    def __init__ (self, value="I am the value from FirstClass"): 
     print value 

    def meth(self): 
     print "I am meth from FirstClass" 

    def meth2(self): 
     print "I am meth2 from FirstClass" 

class SecondClass(FirstClass): 
    def __init__ (self): 
     print "I am in SecondClass" 
     super(SecondClass, self).__init__(value="I am the value from SecondClass") 

    def meth(self): 
     print "I am meth from SecondClass" 


a=FirstClass() # prints "I am the value from FirstClass" 
b=SecondClass() # prints *both* "I am in SecondClass" *and* "I am the value from SecondClass 

a.meth() # prints "I am meth from FirstClass" 
b.meth() # prints "I am meth from SecondClass" 

a.meth2() # prints "I am meth2 from FirstClass" 
b.meth2() # *also* prints "I am meth2 from FirstClass", because you didn't redefine it. 
+0

Cảm ơn bạn ...Bạn có thể cung cấp một ví dụ đơn giản về việc sử dụng siêu từ một lớp thứ hai không? – Louis93

+1

Thêm tải giải thích thêm và một số mã. –

+0

Gotcha. Ví dụ tuyệt vời và giải thích tuyệt vời. Nó cuối cùng đã được nhấp. – Louis93

3

Mã cho SecondClass nên như thế này:

class SecondClass (FirstClass): 
    def meth (self): 
     super (SecondClass,self).__init__(value = "I am a strange string") 
1

chức năng Fix meth

class SecondClass (FirstClass): 
    def meth (self): 
     super (SecondClass,self).__init__(value = "I am a strange string") 
2

Đối số đầu tiên của siêu() nên là hiện lớp, không phải là tầng lớp phụ huynh:

class SecondClass(FirstClass): 
    def meth(self): 
     super(SecondClass, self).__init__(value="I am a strange string") 

Python sẽ tìm thấy hàm thực tế sẽ được ca lled bởi chính nó. Trong trường hợp này, đó là lớp cha 'nhưng điều này có thể không phải là trường hợp khi có nhiều thừa kế.

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