19

I have an abstract class, Model, with a few abstract methods, what should I put in the body of the methods?

  1. A return

    class Model(metaclass=ABCMeta):
        @abstractmethod
        def foo(self):
            return
    
  2. A pass

    class Model(metaclass=ABCMeta):
        @abstractmethod
        def foo(self):
            pass
    
  3. Raising a descriptive error

    class Model(metaclass=ABCMeta):
        @abstractmethod
        def foo(self):
            raise NotImplementedError("Class {class_name} doesn't implement {func_name} function"
                                  .format(class_name=self.__class__.__name__, func_name=self.foo.__name__))
    

Typically I would implement method 3 and raise an error, however it looks like it would be redundant, as Python raises an error for me:

>>> bar = module.Model()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Model with abstract methods foo

Between the options presented, which is best practice? Or is there another way I should handle this?

shayaan
  • 1,482
  • 1
  • 15
  • 32
  • 1
    Don't forget that calling the code is possible, i.e. `super().foo()` is supported. – dhke Aug 22 '17 at 20:51
  • Duplicate of [What should I put in the body of an abstract method in Python](https://stackoverflow.com/q/40894284/2301450). – vaultah Aug 22 '17 at 20:53

1 Answers1

45

The best thing to put in the body of an abstractmethod (or abstractproperty) would be a docstring.

Then you don't need pass or return or ... because a return None is implicitly included - and a docstring makes this construct "compile" without a SyntaxError:

from abc import abstractmethod, ABCMeta

class Model(metaclass=ABCMeta):
    @abstractmethod
    def foo(self):
        """This method foos the model."""

The docstring should then explain what one can expect of this method, so that users and subclassers know what is intended.

MSeifert
  • 145,886
  • 38
  • 333
  • 352
  • 3
    Ah, nice idea! I don't why I didn't think of this. I was about to post an answer using `pass`, but this is a much better idea for the reasons you mentioned. +1 – Christian Dean Aug 22 '17 at 20:56
  • I object to the idea that the docstring should mainly tell sub-classes how to implement this method. First and foremost it should tell the caller what the function does. Any words addressed at implementeres should at most be an after-thought in the docstring – Neuron Jun 07 '22 at 13:10
  • @Neuron-FreedomforUkraine I never said that it should tell **how** to it should be implemented - only what "should be implemented here". I'll see if I can clarify the example and text. – MSeifert Jun 07 '22 at 13:38