0

Suppose I have a base class that has many arguments in the __init__ method. Child class basically starts on top of the base class. Now, I want the child class (at instantiation) to show the docstring (like args, type hints etc) of the base class. I do not want to copy the base class's __init__ arguments manually into the child class __init__ method

So if I have the following code:

# base class
class BaseClass:
  def __init__(self, base_arg1:str,base_arg2:str):
    "this is our base class"
     self.base_arg1 = base_arg1
     self.base_arg2 = base_arg2
     print("running base")

# child
class ChildClass(BaseClass):
  def __init__(self,a:str,b:str):
    "this is our child class"
    super().__init__(a,b)
    return None

In this case, I will first need to write arguments in the child class __init__ method. Then I have to write them again in the super() function. Plus when I am constructing the child class's __init__ method, I need to repeat the docstring/type hinting. Plus, let's say, if later on, another argument gets added to the base class, I will need to copy over the argument (and its docstring/ type hint) to the child class again.

Is there a more efficient way of calling the base class, so that when I call the Child class, type hints and docstring automatically show/pick the Base Classes' argument and docstring? I really want to avoid the double documentation and type hinting for Base & Child Class, whereas arguments both Classes take to instantiate are exactly the same.

Fahadakbar
  • 488
  • 1
  • 8
  • 26
  • 3
    If all you are going to be doing is calling the base init, why override it in the child? – JonSG Mar 28 '22 at 20:35
  • 4
    `when I call the Child class, type hints and docstring automatically show/pick the Base Classes' argument and docstring?`- I'm confused, executing code and writing documentation are two different things. Where exactly do you want the docstring to "show"? You don't need to write `ChildClass.__init__` if it has the same implementation as `BaseClass.__init__`, the inheritance does that for you. – jfaccioni Mar 28 '22 at 20:36
  • @jfaccioni I wanted to avoid writing docstring for child's init, that's what I have already written in the base class. I guess your solution makes sense. If I do not call the __init__ function in the child class, it should get it from the parent class. I will update you once I apply that – Fahadakbar Mar 29 '22 at 15:44

2 Answers2

0

If you are not changing any arguments in child class and they are the same as the parent class then there is no need to call __init__() in child class. When you crate a child class it takes all arguments from parent class. If you want some arguments from parent class and you want to add more arguments then you need to use super().__init__(parent_arg1, parent_arg2). And when you create an object of your child class, it also has all methods from both child and parent class. Btw in your child class __init__() you can't put str: arg it must be arg: str.

BokiX
  • 412
  • 2
  • 14
  • Well, I do need to add more arguments to the child class, so I guess, I have to call the init function for the child class. Does this mean that I will have to map the child's argument to the base's __init__ function and write a docstring for it, the thing I am trying to avoid in the first place? Thanks for the correction. I have editedit – Fahadakbar Mar 29 '22 at 15:34
  • You can check [this question](https://stackoverflow.com/questions/1389180/automatically-initialize-instance-variables) for automatic initialization. But when adding attributes to a child class, you need to either call `super()`, or make new `__init__` but if you want some attributes from parent class, I suggest you using `super()` – BokiX Mar 29 '22 at 15:52
0

Based on the comment of @jfaccioni, I resolved it by not implementing init inside the child class. Now when I instantiate the child class, it behaves like as if I am instantiating Base class.

# base class
class BaseClass:
  def __init__(self, base_arg1:str,base_arg2:str):
    "this is our base class"
     self.base_arg1 = base_arg1
     self.base_arg2 = base_arg2
     print("running base")

# child
class ChildClass(BaseClass):
  def some_other_fun(arg):
    self.arg = arg
    return None
Fahadakbar
  • 488
  • 1
  • 8
  • 26