user14904283
user14904283

Reputation:

What is the point of an @abstractmethod with default implementation?

I’ve seen code that declares abstract methods that actually have a non-trivial body.

What is the point of this since you have to implement in any concrete class anyway?

Is it just to allow you to do something like this?

   def method_a(self):
          super(self).method_a()

Upvotes: 10

Views: 15834

Answers (2)

Yucheng Zhou
Yucheng Zhou

Reputation: 128

The short answer is: Yes.

As described in the Python Documentation of abc:

The abstract methods can be called using any of the normal ‘super’ call mechanisms

PEP3119 also discussed this behavior, and explained it can be useful in the super-call:

Unlike Java’s abstract methods or C++’s pure abstract methods, abstract methods as defined here may have an implementation. This implementation can be called via the super mechanism from the class that overrides it. This could be useful as an end-point for a super-call in framework using cooperative multiple-inheritance [7], [8].

Actually, what the @abstractmethod decorator all do is setting the function's __isabstractmethod__ attribute to True (you can see the implementation code here). And the cooperation of both ABC and @abstractmethod can prevent the instantiation of an abstract class.

So, you can do whatever a normal method can do in an abstract method.

Upvotes: 3

rchome
rchome

Reputation: 2723

I've used this before in cases where it was possible to have the concrete implementation, but I wanted to force subclass implementers to consider if that implementation is appropriate for them.

One specific example: I was implementing an abstract base class with an abstract factory method so subclasses can define their own __init__ function but have a common interface to create them. It was something like

class Foo(ABC):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    @classmethod
    @abstractmethod
    def from_args(cls, a, b, c) -> "Foo":
        return cls(a, b, c)

Subclasses usually only need a subset of the arguments. When testing, it's cumbersome to access the framework which actually uses this factory method, so it's likely someone will forget to implement the from_args factory function since it wouldn't come up in their usual testing. Making it an abstractmethod would make it impossible to initialize the class without first implementing it, and will definitely come up during normal testing.

Upvotes: 7

Related Questions