Подтвердить что ты не робот

TypeError в одиночном наложении Python с атрибутом "супер"

Я никогда не ожидал, что наследование Python 2.7 настолько античеловеческое. Почему следующий код дает мне TypeError?

>>> class P:
...     def __init__(self, argp):
...         self.pstr=argp
... 
>>> class C(P):
...     def __init__(self, argp, argc):
...         super.__init__(self,argp)
...         self.cstr=argc
... 
>>> x=C("parent","child")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: descriptor '__init__' requires a 'super' object but received a 'instance'

Затем я изменил эти 2, все еще неопределенные ошибки:

>>> class C(P):
...     def __init__(self, argp, argc):
...         super().__init__(self,argp)
...         self.cstr=argc
... 
>>> x=C("parent", "child")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: super() takes at least 1 argument (0 given)


>>> class C(P):
...     def __init__(self, argp, argc):
...         super(P).__init__(self,argp)
...         self.cstr=argc
... 
>>> x=C("parent", "child")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: must be type, not classobj

-------- ADD --------

Он по-прежнему не работает, как показано ниже.

>>> class P:
...     def __init__(self, argp):
...         self.pstr=argp
... 
>>> class C(P):
...     def __init__(self, arg1, arg2):
...         super(C, self).__init__(arg1)
...         self.cstr=arg2
... 
>>> z=C("PPP", "CCC")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: must be type, not classobj

--------- ADD2 ----------

Кажется, все 2 приведенные ниже фрагменты кода работают, какая разница? И btw, когда я должен использовать новый класс стиля или старый стиль?

>>> class C(P):
...     def __init__(self, argp, argc):
...         super(C,self).__init__(argp)   #<------ C and self
...         self.cstr=argc
... 
>>> class C(P):
...     def __init__(self, argp, argc):
...         super(P,C).__init__(argp)  #<----- P and C
...         self.cstr=argc
4b9b3361

Ответ 1

В соответствии с версией используемого Python для вашего вопроса возможны два ответа.

Python 2.x

super должен быть вызван следующим образом (пример для документа):

class C(B):
    def method(self, arg):
        super(C, self).method(arg)

В вашем коде это будет:

>>> class P(object):    # <- super works only with new-class style
...     def __init__(self, argp):
...         self.pstr=argp
... 
>>> class C(P):
...     def __init__(self, argp, argc):
...         super(C, self).__init__(argp)
...         self.cstr=argc

В этом случае вам также не нужно передавать self в аргумент.

Python 3.x

В Python 3.x был улучшен метод super: вы можете использовать его без каких-либо параметров (оба теперь являются необязательными), Это решение также может работать, но только с Python 3 и выше:

>>> class C(P):
...     def __init__(self, argp, argc):
...         super().__init__(argp)
...         self.cstr=argc