2009-07-23 22 views
26

Hãy nói rằng tôi có các lớp học sau thành lập:Ví dụ cơ bản về kế thừa đơn bằng cách sử dụng từ khóa super() trong Python là gì?

class Foo: 
    def __init__(self, frob, frotz): 
      self.frobnicate = frob 
      self.frotz = frotz 
class Bar: 
    def __init__(self, frob, frizzle): 
      self.frobnicate = frob 
      self.frotz = 34 
      self.frazzle = frizzle 

Làm thế nào tôi có thể (nếu tôi có thể ở tất cả) sử dụng siêu() trong bối cảnh này để loại bỏ mã trùng lặp?

+0

[http://stackoverflow.com/questions/904036/chain-calling-parent-constructors-in-python](http://stackoverflow.com/question/904036/chain-calling-parent-constructors-in-python) –

Trả lời

25

Trong Python> = 3.0, như thế này:

class Foo(): 
    def __init__(self, frob, frotz) 
     self.frobnicate = frob 
     self.frotz = frotz 

class Bar(Foo): 
    def __init__(self, frob, frizzle) 
     super().__init__(frob, 34) 
     self.frazzle = frizzle 

đọc thêm ở đây: http://docs.python.org/3.1/library/functions.html#super

EDIT: Như đã nói trong câu trả lời khác, đôi khi chỉ cần sử dụng Foo.__init__(self, frob, 34) có thể là giải pháp tốt hơn. (Ví dụ: khi làm việc với một số hình thức thừa kế nhất định.)

+9

Chỉ cần rõ ràng, đây chỉ là python> = 3.0. Đối với pythons cũ (nhưng chỉ những người có "lớp học kiểu mới"), @ire_and_curses trả lời mô tả những gì cần phải làm. –

29

Giả sử bạn muốn lớp Bar để thiết lập giá trị 34 trong constructor của nó, điều này sẽ làm việc:

class Foo(object): 
    def __init__(self, frob, frotz): 
      self.frobnicate = frob 
      self.frotz = frotz 

class Bar(Foo): 
    def __init__(self, frob, frizzle): 
      super(Bar, self).__init__(frob, frizzle) 
      self.frotz = 34 
      self.frazzle = frizzle 


bar = Bar(1,2) 
print "frobnicate:", bar.frobnicate 
print "frotz:", bar.frotz 
print "frazzle:", bar.frazzle 

Tuy nhiên, super giới thiệu các biến chứng riêng của mình. Xem ví dụ super considered harmful. Để hoàn tất, đây là phiên bản tương đương không có super.

class Foo(object): 
    def __init__(self, frob, frotz): 
      self.frobnicate = frob 
      self.frotz = frotz 

class Bar(Foo): 
    def __init__(self, frob, frizzle): 
      Foo.__init__(self, frob, frizzle) 
      self.frotz = 34 
      self.frazzle = frizzle 


bar = Bar(1,2) 
print "frobnicate:", bar.frobnicate 
print "frotz:", bar.frotz 
print "frazzle:", bar.frazzle 
+1

tại sao bạn lại thiết lập Bar.frotz = frizzle thông qua constructor super class sau đó thiết lập nó thành 34 riêng biệt? không nên bạn chỉ có __init __ (frob, 34)? – Victor

+2

Có, điều đó cũng sẽ hoạt động và sẽ sạch hơn. Ví dụ này khá giả tạo (thiết lập một hằng số trong một hàm dựng), nhưng tôi đã cố gắng giữ nguyên bản gốc càng tốt. –

+0

Tôi không biết nếu đó là một cách tốt để làm điều đó ... xem xét trường hợp các nhà xây dựng siêu thực hiện một hoạt động trên frotz và frizzle là một lớp học, mã của bạn sẽ không chạy hoặc những điều tồi tệ hơn nhiều có thể xảy ra. – Victor

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