3

I have been unable to find any questions on this or maybe I am using the wrong nomenclature in my search. If I have something like:

class testone(object):
    def __init__(self):
        self.attone = None
        self.atttwo = None
        self.attthree = None

class testtwo(testone):
    def __init__(self):
        self.attfour = None

And I do:

a = test()
print dir(a)

b = testtwo()
print dir(b)

One can see that a will have all of it's attributes defined as None but b will only have attfour defined even though it inherited class testone. I understand this, but is it possible to make b have all of the attributes inherited from a implicitly defined as well at instantiation ?

I ask b/c I have classes that have tens of attributes that are inheriting from classes with hundreds of attributes and I need every attribute to be defined even if it is of type None so that I don't have to worry about checking if the attribute exists before mapping it from my object to a database table. I am trying not to write as much code. If there is a way to do this then I save well over a thousand lines of code in my class definitions or I could just verify if each attribute exists before mapping the object to my table but that's a lot of code as well as I have a couple thousand attributes to check.

btathalon
  • 185
  • 8
  • You replaced the `__init__` method in the subclass; you want to call the *overridden* version. `super().__init__()` can do that (Python 3), or `super(testtwo, self).__init__()` (both Python 2 and 3). – Martijn Pieters May 06 '16 at 16:50
  • @MartijnPieters not sure how this is a duplicate of that question but oh well. My question does not ask how to "Call a parent class's method" or attribute. My question asks about having all of a parent classes attributes implicitly defined at instantiation of a child class. Also that questioner is already aware of the super solution. I was unaware of super() as it is only mentioned once in the [class inheritance doc](https://docs.python.org/2/tutorial/classes.html#inheritance) and then only when discussing multiple inheritance, which my question had nothing to do with. – btathalon May 06 '16 at 17:52
  • 1
    You'll need to call the parent `__init__` method. I read this as '*how* do I call a parent `__init__` method, rather than '*should* I call the parent `__init__` method?', to which the answer is: "yes, because that method sets those attributes, nothing else". – Martijn Pieters May 06 '16 at 17:57
  • this is why i wrote "maybe I am using the wrong nomenclature in my search". i know what i want but can't put it into words. It hadn't dawned on me that the solution i needed was to call the __init__ method on the parent class. Saying it that way, it does make sense that its a duplicate. thank you for your help. – btathalon May 06 '16 at 18:28

2 Answers2

3

Yes, but since you have overridden __init__ in the derived class, you will have to explicitly init the next class in the mro (a parent or sibling class).

class testone(object):
    def __init__(self):
        self.attone = None
        self.atttwo = None
        self.attthree = None

class testtwo(testone):
    def __init__(self):
        self.attfour = None
        super(testtwo, self).__init__()  # on python3 just use super()

For more details on inheritance, read the docs on super.

Note: I assumed you have meant for testtwo to inherit testone in your question, and have made that correction.

wim
  • 338,267
  • 99
  • 616
  • 750
  • yes you are right, I did intend to inherit 'testone'. I just corrected it. – btathalon May 06 '16 at 16:53
  • This was exactly what I needed. I read the python docs on [class inheritance](https://docs.python.org/2/tutorial/classes.html#inheritance) before asking this but there was no explanation of this and the only mention of super() concerned cases of multiple inheritance so I did not click on super() and read its docs, where it goes on to explain the solution to my situation perfectly. – btathalon May 06 '16 at 17:26
0

Since you overrode testone.__init__ you will have to call the super() function in testtwo. Another thing you can do is take the __init__ variables

class testone(object):
    attone = None
    atttwo = None
    attthree = None

class testtwo(testone):
    attfour = None
notorious.no
  • 4,919
  • 3
  • 20
  • 34