planetp
planetp

Reputation: 16085

Is it a good practice to put common methods to an abstract class in Python?

I'm using the abc module to define an interface that subclasses must support. There're also some common methods that are present in all subclasses. Is it ok to put them in the abstract class or should that only contain abstract methods (i.e. decorated with @abc.abstractmethod) ?

Upvotes: 20

Views: 5510

Answers (1)

freakish
freakish

Reputation: 56477

TL; DR; Yes, it is OK for an abstract class to have non-abstract methods.

Typically what we call an abstract class is just a class that cannot be instantiated.

On the other hand what we call an interface is a class which has only method declarations but no implementations. In particular its an abstract class because it doesn't have a constructor.

Of course in Python there are no real interfaces: every method has to have a body. But we can somewhat emulate interfaces via raise NotImplementedError().

Anyway interfaces form a subset of abstract classes. This obviously suggests that there are abstract classes that are not interfaces. This is exactly the case you are describing. Yes, abstract class may contain implemented, non-abstract methods. And it is not a bad practice. This is especially useful when a given method does not depend on concrete implementation.


For example consider an interface for a generic parser (I'm thinking about json.load and json.loads):

class ILoader(ABC):
    @abstractmethod
    def load(self, stream):
        raise NotImplementedError()

It's completely OK to give loads method which accepts a string instead of stream with a default implementation:

class AbstractLoader(ABC):
    @abstractmethod
    def load(self, stream):
        raise NotImplementedError()

    def loads(self, text):
        stream = io.StringIO(text)
        return self.load(stream)

although I would use Abstract prefix instead of I. ;)

Upvotes: 19

Related Questions