Search code examples
pythonabstract-classclass-method

Can we call a method from within a class of no instantiation


I would like to ask if there is a way to implement an interface method within a class without instantiation, or even more, if it is altogether a bad practice? If so, what will be the right way to implement a complex interface method?

Here is a prototype of my code:

class calculator(abc.ABC):

    @abc.abstractmethod
    def calculate(self):
        "start model"

class subcalculator(calculator):
    def calculate(self):
        return model.attr2 ** 3

    def recalculate(self):
        z = calculate(self)
        return z ** 2

However, this reports calculate() is not defined when run subcalculator.recalculate as it is not instantiated.

As I am just writing interface classes for my model, I suppose writing initiation is not a good idea.(Or is it?) What should I do then in such case?

Edit: According to @chepner 's answer, I have also figured out some hackish way to solve this problem, which I am not sure if it's right practice:

    @classmethod
    def recalculate(cls, self):
        z = cls.calculate(self)
        return z ** 2

Also it's worth mentioning the object/model part of the structure:

#In model.py

class model(object):
    def __init__(self, attr1):
        self.attr1 = attr1

class submodel(model):
    def __init__(self, attr1, attr2):
        super().__init__(attr1)
        self.attr2 = attr2

So my hope is to write calculator as an interface class which can interact with model etc.


Solution

  • calculate is a method whether or not you ever create an instance, and has to be referred to as such.

    class subcalculator(calculator):
        def calculate(self):
            return model.attr2 ** 3
    
        def recalculate(self):
            z = subcalculator.calculate(self)
            return z ** 2
    

    Of course, it's better to let the inheritance model determine exactly which calculate method needs to be called:

    def recalculate(self):
        z = self.calculate()
        return z ** 2