Reputation:
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
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
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