4
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__()

4
  • 4
    Your code as written is horribly broken. Please verify that the anonymized code still works before submitting it. Commented Nov 15, 2011 at 10:01
  • 1
    PEP 8 would like you to rename baseClass to BaseClass, derivedClass to DerivedClass and put in spaces after the commas in the arguments of the method declarations. Commented Nov 15, 2011 at 10:02
  • 1
    currently, the derived class has no relation to your base class. And why do not you use new-style classes? Commented Nov 15, 2011 at 10:05
  • @ Ignacio Vazquez-Abrams .It has nothing to do with anonymity.I was working in django & I came across this problem.I knew its a python problem.So there was no need to put all the complexities of django forms & views in here.Nevertheless my apologies for the broken code Commented Nov 16, 2011 at 5:22

4 Answers 4

10

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
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks.But what is it with # you're using named parameters, declare them as named one..If I don't give default values to arguments it won't be named arguments?
@Jibin : you call derivedClass(name='Jibin'), this is a named parameter, it is more coherent if you declare this parameter as a named one.
Its just that I don't wan't to give default values to arguments to make it required arguments.
0

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.

Comments

0

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)

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.