2009-07-23 8 views
26

Скажем, у меня есть следующие классы настройки:Что такое базовый пример одиночного наследования с использованием ключевого слова super() в Python?

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 

Как я могу (если я могу вообще) использовать супер() в этом контексте, чтобы исключить дублирование кода?

+0

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

ответ

25

В Python> = 3.0, например:

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 

Подробнее здесь: http://docs.python.org/3.1/library/functions.html#super

EDIT: Как было сказано в другом ответе, иногда только с помощью Foo.__init__(self, frob, 34) может быть лучшим решением. (Например, при работе с определенными формами множественного наследования.)

+9

Чтобы быть понятным, это только python> = 3.0. Для старших питонов (но только для тех, кто имеет «классы нового стиля»), @ire_and_curses отвечает, что нужно сделать. –

29

Предполагая, что вы хотите класса Bar, чтобы установить значение 34 в пределах своего конструктора, это будет работать:

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 

Однако super вносит свои осложнения. См. super considered harmful. Для полноты, вот эквивалентная версия без 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

Почему вы устанавливаете Bar.frotz = frizzle через конструктор суперкласса, а затем устанавливаете его на 34 отдельно? разве у вас просто нет __init __ (frob, 34)? – Victor

+2

Да, это тоже сработает и будет чище. Пример довольно ухищрен (установка константы в конструкторе), но я старался как можно ближе подойти к оригиналу. –

+0

Я не знаю, если это хороший способ сделать это ... рассмотрите случай, когда суперконструктор выполняет операцию на frotz, а frizzle - это класс, ваш код не будет работать или что-то еще хуже. – Victor