views:

74

answers:

5

In python OOP, lets say, Person is a parent class with its own constructor; then Student is a sub class of Person, before I use Student, must Person.__init__(self) be called first in the constructor of Student? Plus, can I define a new constructor in Student class?

class Person():      
    def __init__(self):  

Above is class Person with its constructor

class Student(Person):    
    def __init__(self):  
        Person.__init__(self)   
    def __init__(self, age)

What I mean is, could Student have its own constructor? If so, must Person.__init__(self) be called in the Student constructor in this case?

A: 

It doesn't have to be, no, but it really should. If the base class has any methods or properties which aren't overridden in the derived class then the base class should be initialized properly, otherwise those methods and properties may not work.

EDIT: let me clarify. You can define a constructor for Student, but that constructor really should call Person.__init__ to make sure the base class is initialized properly.

Peter Milley
@Peter Thank you :)
ladyfafa
A: 

Student can have a own constructor. In python you may or may not call the base class constructor, but it is good practice to do so.

IanH
@lanH thanks !!
ladyfafa
A: 

No it would look like this:

class Person(object):
    def __init__(self, name, age, height, weight):
        self.name = name
        self.age = age
        self.height = height
        self.weigth = weight


class Student(Person):
    def __init__(self, name, age, height, weight, school):
        Person.__init__(self, name, age, heigth, weight)
        self.school = school

If you didn't have Person.__init__ in the Student class, you would have to do all the things you do in the Person class in the Student class if you wanted to be able to use it like a person.

Zimm3r
I see now, thank you :)
ladyfafa
@sth, btw, may I know how to edit the code into a nice format when I tried to post any piece of code here? Your code looks nice
ladyfafa
ladyfafa: Just indent the code lines by 4 spaces (+ the spaces for the python code) and Stackoverflow will colorize it automagically.
IanH
@lanH, thanks ~~
ladyfafa
@ladyfafa: For code blocks indent all the lines with for spaces, for example by selecting the code and clicking the 101010-button in the editor (Or using the Ctrl-K keyboard shortcut). For inline code use backticks, or that same button/shortcut. For more see http://stackoverflow.com/editing-help or the explanations shown to the right of the edit window.
sth
Also, you should be using `super`.
Aaron Gallagher
@ Aaron Gallapher you can but I find it causes over confusion for something that is already confusing, Object Oriented Programing.
Zimm3r
@Zimm3r, super makes things *less* confusing. What's so much more confusing about the method call in my answer?
Aaron Gallagher
@ Aaron I guess it is a matter of what parts of OOP you understand at the time.
Zimm3r
Regarding `super()` there are some caveats, read this: http://fuhm.net/super-harmful/
clacke
A: 

Adapted from Zimm3r's answer, but using super for maximum correctness:

class Person(object):
    def __init__(self, name, age, height, weight):
        self.name = name
        self.age = age
        self.height = height
        self.weigth = weight


class Student(Person):
    def __init__(self, name, age, height, weight, school):
        super(Student, self).__init__(name, age, heigth, weight)
        self.school = school
Aaron Gallagher
super works fine, just like java
ladyfafa
+1  A: 

Of course, Student can have its own constructor. However, a class can only have one constructor in Python, there's nothing like constructor overload.

So when we say a sub class has its own constructor, we really mean something like this:

class Worker(People):
    def __init__(self, company):
        self.company = company

As @IanH pointed out, you don't have to call the super class constructor. And when you think you should call it (probably for some common initialization), you can do it like this:

class People:
    def __init__(self, name):
        self.name = name

class Student(People):
    def __init__(self, name, school):
        super(Student, self).__init__(name)
        self.school = school
Satoru.Logic
that could be brilliant, my concern is the so called "constructor overload", now i am on my way
ladyfafa
This is the right way to do it, but learn more about what `super()` really does here: http://fuhm.net/super-harmful/ . It's a good read in a more general sense also, as the point of using **kwargs and keyword parameters is useful in many situations.
clacke
Thanks for sharing the link. But if I understood this essay correctly, it is evil only when you try to use multi-inheritance, right? So I think it is multi-inheritance that's harmful :)
Satoru.Logic