13

I'm trying to understand how to use super in python

class people:   
 name = ''  
 age = 0  
  __weight = 0  

 def __init__(self,n,a,w):  
    self.name = n  
    self.age = a  
    self.__weight = w  
def speak(self):  
    print("%s is speaking: I am %d years old" %(self.name,self.age))  


class student(people):  
 grade = ''  
 def __init__(self,n,a,w,g):  
    #people.__init__(self,n,a,w)  
    super(student,self).__init__(self,n,a,w)
    self.grade = g  

 def speak(self):  
    print("%s is speaking: I am %d years old,and I am in grade %d"%(self.name,self.age,self.grade))  


s = student('ken',20,60,3)  
s.speak()

The above code gets following error:

---------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-147-9da355910141> in <module>()
     10 
     11 
---> 12 s = student('ken',20,60,3)
     13 s.speak()

<ipython-input-147-9da355910141> in __init__(self, n, a, w, g)
      3     def __init__(self,n,a,w,g):
      4         #people.__init__(self,n,a,w)
----> 5         super(student).__init__(self,n,a,w)
      6         self.grade = g
      7 

TypeError: must be type, not classobj

I'm confused about why I cannot use super(student,self).__init__(self,n,a,w) in this case, and why I have to use people.__init__(self,n,a,w)

Any help?

khelwood
  • 55,782
  • 14
  • 81
  • 108
ikel
  • 1,790
  • 6
  • 31
  • 61

1 Answers1

29

Your base class people should be derived from the object class, to make it a new-style class, which will allow super() to work.

You should then use super as:

super(student, self).__init__(n,a,w)

Old-style classes behave quite differently, and I don't understand them

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
Simon Callan
  • 3,020
  • 1
  • 23
  • 34
  • ok, i make some changes accordingly on people class : class people(object) , now if use super(student, self).__init__(self,n,a,w), i got TypeError: __init__() takes exactly 4 arguments (5 given), why is that? – ikel Jun 28 '16 at 09:43
  • No need to pass `self` as an argument to a bound `__init__` of super object. – Ilja Everilä Jun 28 '16 at 09:45
  • @IljaEverilä removing self from init worked ! just one more question, why do you call people(object) new style? is this new in python 2.7 vs. previous versions? – ikel Jun 28 '16 at 09:50
  • 1
    See ["New-style and classic classes"](https://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes) in the docs. – Ilja Everilä Jun 28 '16 at 09:51
  • @ikel So alled "new-style" classes appeared with python 2.2 or so. The "old style" ones were kept until python2.7 for backward compatibility and were removed in python3. I don't think you should waste reading reading about them since they are pretty much "done" now. just remember to always give the `object` base class and you wont have problems anymore. – Bakuriu Jun 28 '16 at 10:02