Я правильно использую super ()? - PullRequest
6 голосов
/ 30 июня 2011

Я сделал небольшой кусок кода, потому что я все еще пытаюсь выяснить особенности использования super().Почему этот блок работает с TypeError?

 a = SecondClass()
TypeError: __init__() takes exactly 2 arguments (1 given)

Затем функция SecondClass.meth() должна печатать строку, но я явно что-то упускаю концептуально.

class FirstClass (object):
    def __init__ (self, value):
        self.value = value
        print self.value

class SecondClass (FirstClass):
    def meth (self):
        super (FirstClass,self).__init__(value = "I am a strange string")

a = SecondClass()
a.meth()

Ответы [ 5 ]

8 голосов
/ 30 июня 2011

Это не имеет ничего общего с super.Вы не определяете __init__ для SecondClass явно - но, поскольку он наследуется от FirstClass, он наследует FirstClass '__init__.Таким образом, вы не можете создать экземпляр объекта, не передав параметр value.

Редактировать ОК.Во-первых, как уже упоминали другие, вы должны всегда использовать класс current в своем супер-вызове, а не суперкласс - в данном случае super(SecondClass, self).Это потому, что super означает «получить родителя класса x», поэтому очевидно, что вы имеете в виду «получить родителя SecondClass», то есть FirstClass.

Второй момент заключается в том, что не имеет смысла вызывать __init__ метод внутри meth.__init__ уже уже вызывается при создании экземпляра объекта.Либо ваш подкласс определяет свою собственную версию, которая может выбирать, вызывать или не вызывать свой собственный супер-метод;или, как в этом случае, это не так, и в этом случае версия суперкласса вызывается автоматически.

Позвольте мне повторить это, потому что я подозреваю, что это недостающий фрагмент в вашем понимании: весь смыслподкласс - это то, что все, что вы не переопределяете, все равно наследуется.super это только для тех случаев, когда вы хотите что-то переопределить, но при этом использовать логику из суперкласса .

Так что вот глупый пример:

class FirstClass(object):
    def __init__ (self, value="I am the value from FirstClass"):
        print value

    def meth(self):
        print "I am meth from FirstClass"

    def meth2(self):
        print "I am meth2 from FirstClass"

class SecondClass(FirstClass):
    def __init__ (self):
        print "I am in SecondClass"
        super(SecondClass, self).__init__(value="I am the value from SecondClass")

    def meth(self):
        print "I am meth from SecondClass"


a=FirstClass() # prints "I am the value from FirstClass"
b=SecondClass() # prints *both* "I am in SecondClass" *and* "I am the value from SecondClass

a.meth() # prints "I am meth from FirstClass"
b.meth() # prints "I am meth from SecondClass"

a.meth2() # prints "I am meth2 from FirstClass"
b.meth2() # *also* prints "I am meth2 from FirstClass", because you didn't redefine it.
3 голосов
/ 30 июня 2011

Код для SecondClass должен быть таким:

class SecondClass (FirstClass):
    def meth (self):
        super (SecondClass,self).__init__(value = "I am a strange string")
2 голосов
/ 30 июня 2011

Первым аргументом super () должен быть класс current , а не родительский класс:

class SecondClass(FirstClass):
    def meth(self):
        super(SecondClass, self).__init__(value="I am a strange string")

Python найдет фактическую функцию, которая будет вызываться сама по себе.В данном случае это родительский класс, но это может быть не так, если задействовано множественное наследование.

1 голос
/ 30 июня 2011

Исправить функцию мета

class SecondClass (FirstClass):
    def meth (self):
        super (SecondClass,self).__init__(value = "I am a strange string")
1 голос
/ 30 июня 2011

должно быть

super(SecondClass, self)

См. документацию по Python для super ()

...