Reputation: 3102
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
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
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
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
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