Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError in Python single inheritance with "super" attribute

Tags:

python

I never expected the inheritance of Python 2.7 is so anti-human. Why the following code give me a 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'

Then I changed to these 2, still vague errors:

>>> 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--------

It still doesn't work as below.

>>> 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----------

It seems all the 2 below code snippets work, what's the difference? And btw, when should I use the new style class or the old style class?

>>> 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
like image 742
smwikipedia Avatar asked Jan 11 '14 14:01

smwikipedia


1 Answers

There are two responses possible for your question, according to the version of Python you're using.

Python 2.x

super has to be called like this (example for the doc):

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

In your code, that would be:

>>> 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

You also don't have to pass self in argument in this case.

Python 3.x

In Python 3.x, the super method has been improved: you can use it without any parameters (both are optional now). This solution can work too, but with Python 3 and greater only:

>>> class C(P):
...     def __init__(self, argp, argc):
...         super().__init__(argp)
...         self.cstr=argc
like image 118
Maxime Lorant Avatar answered Sep 21 '22 17:09

Maxime Lorant