Проблема наследования Python 3 - PullRequest
0 голосов
/ 07 ноября 2018

Я новичок в Python и у меня проблемы с наследованием и использованием супер ()

Код ниже дает мне эту ошибку

Произошло исключение: AttributeError Объект 'ObjB' не имеет атрибута 'job'

Но я не уверен, почему, поскольку задание является атрибутом ObjB

Тестовый код это ..

class ObjA():
    def __init__(self, astr):
        self.name = astr
        self.decorate()

    def decorate(self):
        self.name = '['+self.name+']'

class ObjB(ObjA):
    def __init__(self, aname, ajob):
        super().__init__(aname)
        self.job = ajob

    def decorate(self):
        super().decorate()
        self.name = self.name + ' is a ' + self.job

test = ObjA('Fred')
print(test.name)

test2 = ObjB('Fred', 'Baker')
print(test2.name)

Чего я ожидал, так это

[Fred]
[Fred] is a Baker

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Ключевым моментом является то, что когда вы используете super в подклассе для вызова __init__ в базовом классе, self, переданный __init__ , является экземпляром подкласса ObjB, а не ObjA. Следовательно, self.decorate() в ObjA в __init__ фактически вызывает метод decorate в ObjB, поэтому job не определен.

super().__init__ работает следующим образом: ObjA.__init__(test2)

Ниже приводится от Документы Python о наследовании

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

0 голосов
/ 07 ноября 2018

В вашем методе ObjB.__init__() вы вызываете super().__init__(aname) перед тем, как установить self.job = ajob, поэтому при вызове методов decorate self.job еще не установлено. Попробуйте переместить self.job = ajob ранее в методе __init__(), например:

class ObjB(ObjA):
    def __init__(self, aname, ajob):
        self.job = ajob
        super().__init__(aname)

Другим способом решения проблемы является полное устранение методов decorate():

class ObjA():
    def __init__(self, astr):
        self.name = '['+astr+']'


class ObjB(ObjA):
    def __init__(self, aname, ajob):
        super().__init__(aname)
        self.job = ajob
        self.name = self.name + ' is a ' + self.job
...