ladyfafa
ladyfafa

Reputation: 7269

python sub class initialiser

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

class Person():      
    def __init__(self):  

Above is class Person with its initialiser

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

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

Upvotes: 4

Views: 20043

Answers (6)

Peter Milley
Peter Milley

Reputation: 2808

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 initialiser from the base class should be called, otherwise those methods and properties may not work.

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

Upvotes: 1

IanH
IanH

Reputation: 4048

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

Upvotes: 1

satoru
satoru

Reputation: 33225

Of course, Student can have its own initialiser. However, a class can only have one initialiser in Python, because that is a special method called within the constructor (the class __new__ method).

So when we say a sub class has its own initialiser, 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 initialiser. 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

Upvotes: 9

Volodymyr  Prysiazhniuk
Volodymyr Prysiazhniuk

Reputation: 1913

You can overload Python's __new__ it goes before __init__, that what you was looking in your original question.

def __new__(cls, *args, **kwargs):pass

Upvotes: 0

habnabit
habnabit

Reputation: 10274

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

Upvotes: 0

Zimm3r
Zimm3r

Reputation: 3425

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.

Upvotes: 4

Related Questions