0

I'm not too familiar with the use of abstract classes, so I'm trying to understand what is happening in some code I'm using at the moment.

In the code, I have a base dataset class, and some implementations of datasets inheriting from the main one, something like:

class dataset(metaclass=abc.ABCMeta):
    def __init__():
        # implementation of __init__

    @abc.abstractmethod
    def _some_method(self, ....):
        return


class dataset_01(dataset):
    def _some_method(self, ....):
        # implementation of _some_method for dataset_01, overriding abstract method from base class

What I don't understand is, I was expecting to see a call for super().__init__() in dataset_01:

class dataset_01(dataset):
    def __init__(self, length):
        super().__init__(...)

There's no such call, but when debugging the code, I noticed that I still end up in the constructor of dataset when creating an instance of dataset_01, in spite of the missing super.

Is the use of metaclass=abc.ABCMeta in the dataset class leading to some automatic method resolution, i.e. is it ensuring that the __init__ method of the base class is called anyway? Or am I missing something else?

Carlo
  • 1,321
  • 12
  • 37
  • 5
    If you don't override a method in a subclass, it automatically inherits the base class method. You only need to call `super().__init__()` if the subclass has its own `__init__()` method. – Barmar Aug 30 '23 at 16:47
  • 2
    "What I don't understand is, I was expecting to see a call for `super().__init__() in dataset_01`" can you elaborate on **why** you were expecting that? – juanpa.arrivillaga Aug 30 '23 at 16:50
  • 1
    "Is the use of `metaclass=abc.ABCMeta` in the dataset class leading to some automatic method resolution, i.e. is it ensuring that the `__init__` method of the base class is called anyway?" No, this has nothing to do with `abc`, this is just inheritance. Indeed it's the whole point of inheritance. You can create a `class Foo` that defines an `__init__` which just prints something, then just `class Bar(Foo): pass` then you'll see `Bar()` calls that initializer you wrote in `Foo` – juanpa.arrivillaga Aug 30 '23 at 16:53
  • This is kinda embarrassing, but not having worked with inheritance in Python that much, I completely missed that the methods are automatically inherited, I was assuming you always need to use super() calls for that. @juanpa.arrivillaga, this also answers your question about why I was expecting 'super().__init__()' in dataset_01. Thanks a lot for the clarification! – Carlo Aug 31 '23 at 06:33
  • so, I only asked because in some languages constructors treated specially in inheritance, so a lot of people coming grom those languages write an unecessary override of `__init__` that simply calls `super().__init__` – juanpa.arrivillaga Aug 31 '23 at 07:44

1 Answers1

1

When you create a subclass in Python, if that subclass does not have its own __init__() method, it will automatically inherit the __init__() method from the parent class. That's why, even if you haven't explicitly called super().__init__() in dataset_01, the constructor of the parent class dataset is still invoked when you create an instance of dataset_01.

The use of metaclass=abc.ABCMeta does not affect this behavior. Its primary purpose is to ensure that the class containing this metaclass cannot be instantiated directly (because it's an abstract class) and that all its abstract methods must be implemented by any non-abstract subclass.

In summary, the behavior you observe is standard in Python and is not specific to the use of abstract classes.