2015-02-16 1 views
3

Я изучаю стиль python oop. Мне показался __init__ метод строительства, как показано ниже. Раньше я этого стиля не видел. Зачем использовать двойные методы __init__, как в этом?Почему двойной __init__ в python?

экс-

class MinimumBalanceAccount(BankAccount): 
    def __init__(self, minimum_balance): 
     BankAccount.__init__(self) 
     self.minimum_balance = minimum_balance 

    def withdraw(self, amount): 
     if self.balance - amount < self.minimum_balance: 
      print 'Sorry, minimum balance must be maintained.' 
     else: 
      BankAccount.withdraw(self, amount) 
+0

Это просто [Понимание Python super() с методами __init __()] (http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods) в маскировке. Но не совсем дубликат, так как неясно, что происходит, если код не говорит 'super (...) .__ init __()'. – smci

ответ

5

Это пример наследования класса в Python. Вы унаследовали класс BankAccount к классу MinimumBalanceAccount. Однако, введя функцию __init__ в классе MinimumBalanceAccount, вы переопределили функцию __init__ от BankAccount класса. Базовый класс может инициализировать некоторые переменные, необходимые для вас. И поэтому он вызывается в классе Child '__init__, чтобы гарантировать это.

Вы можете использовать класс super для реализации такого же поведения. В Python 2.x, эквивалент будет

class MinimumBalanceAccount(BankAccount): 
    def __init__(self, minimum_balance): 
     self.minimum_balance = minimum_balance 
     super(MinimumBalanceAccount, self).__init__() 

Или в Python 3.x,

class MinimumBalanceAccount(BankAccount): 
    def __init__(self, minimum_balance): 
     super().__init__() 

Однако, вы должны понимать, что это будет просто запускать любые __init__ метод, который он находит первый из базовые методы. Таким образом, с точки зрения множественного наследования было бы сложно вызвать методы __init__ различных классов, если super не реализован в базовых классах. Поэтому, пожалуйста, избегайте использования множественного наследования любой ценой или реализуйте super во всех классах.

(eg) 

class BankAccount(object): 
    def __init__(self): 
     # Some action here 
     # But no super method called here 

class MinimumBalanceAccount(BankAccount, LoanAccount): 
    def __init__(self, minimum_value): 
     super(MinimumBalanceAccount, self).__init__() # Calls BankAccount.__init__() 
     super(MinimumBalanceAccount, self).__init__() # Still calls the same 

Если вы все еще хотите, чтобы пойти для множественного наследования, лучше идти с ParentClass.__init__ подходом или добавить вызов метода super к __init__ во всех базовых классов.

+1

«Тем не менее, вы должны понять, что это просто запустит любой метод init, который он найдет первым из базовых методов». => извините, но это по крайней мере частично неправильно. - до тех пор, пока методы родительских классов '__init__' выполняют' super().__init __() 'вызывают себя, тогда инициализаторы родительского элемента будут вызываться в правильном порядке (т. е. порядке' __mro__'). –

+0

Да. Если в родительском классе есть супервызов. Затем с помощью одного супер-утверждения мы будем следовать всей резолюции. Однако, если в базовом классе нет супер метода, мы не могли бы получить второй метод '__init__', отличный от вызова по имени класса. Я уточню сообщение более подробно. – thiruvenkadam

1

Класс MinimumBalanceAccount происходит от класса BankAccount. Поэтому в функции класса init необходимо вызвать init базового класса, который выполняется BankAccount.__init__(self).

1

Это не более, чем вызов ParentClass.__init__() в маскировке, т.е.

super(ChildClass, self).__init__() 

Предпочтительный стиль Python является явно использовать супер, а не жёстко во имя родительского класса.

(В Python 3.x: вы можете просто сказать super().__init__())

Так что это на самом деле просто Understanding Python super() with init() methods в маскировке; здесь, ChildClass является MinimumBalanceAccount