Jibin
Jibin

Reputation: 3102

python constructor of derived class

class baseClass():
  def __init__(self,mark,name):
    self.mark = mark
    self.name = name

class derivedClass(baseClass):

b1 = derivedClass(name='Jibin')
print b1.name

This was my code initially & it worked fine.

(Note: I don't have access to baseClass)

But later I had to pass a additional attribute rank to derivedClass.So I edited the code like this.

class baseClass():
  def __init__(self,mark,name):
    self.mark = mark
    self.name = name

class derivedClass(baseClass):
  def __init__(self,rank):
    self.rank = rank 

b1 = derivedClass(name='Jibin')
print b1.name

This caused an error __init__() got an unexpected keyword argument 'name'

This was expected as the __init__ of derivedClass do not have a argument name.

I don't want to add an additional argument name to __init__ of derivedClass b'cos in real baseClass has ten arguments instead of 2(mark,name) & if i give all them as additional argument to derivedClass I will be cluttering its argument list.

Note: I am aware of initializing baseClass using baseClass.__init__(self) or super(derivedClass, self).__init__()

Upvotes: 4

Views: 12874

Answers (4)

Cédric Julien
Cédric Julien

Reputation: 80751

Maybe you can try something like this

class BaseClass(object):
  def __init__(self, mark=None, name=None):   # you're using named parameters, declare them as named one.
    self.mark = mark
    self.name = name

class DerivedClass(BaseClass):   # don't forget to declare inheritance
  def __init__(self, rank=None, *args, **kwargs):    # in args, kwargs, there will be all parameters you don't care, but needed for baseClass
    super(DerivedClass, self).__init__(*args, **kwargs)
    self.rank = rank 

b1 = DerivedClass(name='Jibin')
print b1.name

Upvotes: 10

YuanZheCSYZ
YuanZheCSYZ

Reputation: 45

Have you guys tried [Python] cast base class to derived class

I have tested it, and seems it works. Also I think this method is bit better than below one since below one does not execute init function of derived function.

c.__class__ = CirclePlus

Upvotes: 0

Rob Cowie
Rob Cowie

Reputation: 22619

derivedClass is not in fact derived from baseClass. To subclass in python you must provide the parent class to the class definition thus:

class DerivedClass(BaseClass):
    pass

DerivedClass now inherits the methods of BaseClass, including __init__(). If you do not override a method, calling it on your subclass actually calls the method as defined on the superclass.

So, if you want to allow DerivedClass(name='Jibin'), you need to provide a specialised init():

class BaseClass(object):
    def __init__(self, mark, name):
        self.mark = mark
        self.name = name

class DerivedClass(BaseClass):
    def __init__(self, mark, name, rank):
        BaseClass.__init__(self, mark, name)
        self.rank = rank

Now, you also want to support additional keyword arguments to DerivedClass() without adding them explicitly. One way to achieve this is to assign all kwargs to instance attributes, thus:

class BaseClass(object):
    def __init__(self, mark, name, **kwargs):
        self.mark = mark
        self.name = name
        self.__dict__.update(kwargs)

I don't advise this 'for real' though. Blindly setting attributes is likely to introduce subtle bugs in the future (such things as unknowingly replacing a method by passing a keyword arg of the same name)

Upvotes: 0

Björn Pollex
Björn Pollex

Reputation: 76788

This blog describes how to solve this sort of problem. The solution is to have base as well as derived accept a **kwargs argument in their __init__ and pass that to the call to super.

Upvotes: 0

Related Questions