Метод наследования и инициализации в Python


94

Я новичок в питоне. Я не могу понять наследование и __init__().

class Num:
    def __init__(self,num):
        self.n1 = num

class Num2(Num):
    def show(self):
        print self.n1

mynumber = Num2(8)
mynumber.show()

РЕЗУЛЬТАТ: 8

Хорошо. Но я заменяю Num2на

class Num2(Num):
    def __init__(self,num):
        self.n2 = num*2
    def show(self):
        print self.n1,self.n2

РЕЗУЛЬТАТ: Error. Num2 has no attribute "n1".

В таком случае как получить Num2доступ n1?

Ответы:


148

В первой ситуации Num2это расширение класса, Numи поскольку вы не переопределяете специальный метод с именем __init__()in Num2, он наследуется от Num.

Когда класс определяет __init__() метод, создание экземпляра класса автоматически вызывается __init__()для вновь созданного экземпляра класса.

Во втором случае, так как вы пересматриваете __init__()в Num2вам нужно явно вызвать один в супер класс ( Num) , если вы хотите продлить свое поведение.

class Num2(Num):
    def __init__(self,num):
        Num.__init__(self,num)
        self.n2 = num*2

23
Вашей цитаты недостаточно, чтобы объяснить, почему, когда __init__метод не определяется в производном классе, он наследуется. Это потому, что «если запрошенный атрибут не найден в классе, поиск продолжается в базовом классе». (doc)
eyquem

5
Мне очень жаль ... это в основном принцип работы наследования ... если вы наследуете класс, вы получаете весь пакет, поэтому все в суперклассе существует в подклассе. Но если вы переопределите метод, он переопределится ... это то, что происходит в вашем коде.
coya

4
@ mario-duarte, почему это лучше super(Num2, self).__init__(num)?
guival

1
Я только что переключился с решения, предложенного в этом ответе, на использование super, и теперь моя программа загружается на несколько секунд быстрее. Понятия не имею почему.
Guimoute

superдолжен быть полезен при использовании множественного наследования. Для единоличного наследования его преимущества не очевидны.
Иоганн Бж



3

Простое изменение в классе Num2, например:

super().__init__(num) 

Он работает в python3.

class Num:
        def __init__(self,num):
                self.n1 = num

class Num2(Num):
        def __init__(self,num):
                super().__init__(num)
                self.n2 = num*2
        def show(self):
                print (self.n1,self.n2)

mynumber = Num2(8)
mynumber.show()

1
Вот почему я люблю stackoverflow. Хотя это не ответ на вопрос, это полезно. Иногда ответы, которые публикуют люди, являются ответами на вопрос, который люди должны были задать. Спасибо!
Глен Томпсон,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.