1
class base():
    def __init__(self):
        self.var = 10
        
    def add(self, num):
        res = self.var+num
        return res
    
class inherit(base):
    def __init__(self, num=10):
        x = super().add(num)

a = inherit()
print(a)

Hello, I'm learning about inheritance and super(). When running this, the error AttributeError: 'inherit' object has no attribute 'var' is returned. How can I inherit the init variables too?

Bigboss01
  • 438
  • 6
  • 21

1 Answers1

2

You first need to call super constructor because you did not define var in your base class constructor.

Working version of your code (though you should probably add var in base __init__)

class Base:
    def __init__(self):
        self.var = 10

    def add(self, num):
        res = self.var + num
        return res


class Inherit(Base):
    def __init__(self, num=10):
        super().__init__()
        x = super().add(num)


a = Inherit()
print(a)

one possible solution

    class Base:
        def __init__(self, var=10):
            self.var = var
    
        def add(self, num):
            res = self.var + num
            return res
    
    
    class Inherit(Base):
        pass


a = Inherit()
a.add(0)  # replace 0 with any integer
May.D
  • 1,832
  • 1
  • 18
  • 34
  • Also if you are working with Python 3, class Base should explicitely inherit `object` – May.D Aug 19 '21 at 21:54
  • 3
    You've got that backwards. If you're using Python 2 then it should inherit from object. In Python 3 it's not needed. – John Gordon Aug 19 '21 at 21:55
  • I think PEP says that though it's not required it's a good practice, I will give a look to this. – May.D Aug 19 '21 at 21:57
  • https://stackoverflow.com/a/1238632/8237838 second comments of this answer provides more accurate information on this topic, but anyway I'd rather refer to PEP20 Explicit is better than implicit (especially for beginners) :https://www.python.org/dev/peps/pep-0020/ – May.D Aug 19 '21 at 22:02
  • thank you for your answer @May.D . How is var defined if not how I did it? – Bigboss01 Aug 19 '21 at 22:02
  • I'm not sure what your need is, but have a look to my edited answer for one possible solution. – May.D Aug 19 '21 at 22:08
  • The terminology here is not quite right - `__init__` is an initializer. There is a different class method `__new__` that does the constructing. Its quite unusual to have a case where you need a different `__new__` so it doesn't pop up much in conversation. – tdelaney Aug 19 '21 at 22:16
  • 1
    @May.D - Python 2 classes did not inherit from `object` originally. That was introduced when class semantics changed from "old style" to "new style" classes, and was something of a dirty hack. Since python 3, all classes are "new style" classes and the dirty hack isn't needed. Its really only there for backwards compatibility. This is one of those cases where I don't think that explicit wins. – tdelaney Aug 19 '21 at 22:19
  • @tdelaney Please feel free to edit my answer with more accurate terms, I'm still a junior Python programmer and have few experience with Python 2. Anyway, though `object` inheritance is not required anymore, IMHO it increases readability and backward portage so just why not :) – May.D Aug 19 '21 at 22:25
  • @tdelaney: I think this is also due to another general rule (you will forgive that I don't remember the phrasing, but I'm sure it's somewhere in the PEPs, possibly implicitly ;) ): you should not write meaningless code. Explicitly inheriting from `object` provides *no* extra information in Python 3 code, it's just useless clutter. Similarly to putting C-style parentheses in a conditional or loop declaration - you can put them there, but they don't help. Same with semicolons. (It is also arguably an instance of "There should be one-- and preferably only one --obvious way to do it." from Zen) – tomasz Aug 20 '21 at 00:02
  • (There may be exceptions of course, when explicitly inheriting from `object` *does* provide information and alters behaviour: when doing multiple inheritance with `object` not appearing last. But that would not even work with the default MRO.) – tomasz Aug 20 '21 at 00:04
  • 1
    @tomasz - that's a good point. An example is explicitly stating default arguments. `open("whatever", "r")` for instance subtly makes a reviewer think twice... – tdelaney Aug 20 '21 at 05:06