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.
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.
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.
inheritance - Abstract methods in Python - Stack Overflow
AbstractMethods and NotImplementedError
Implement Base classes as AbstractBaseClasses
Issue with abstract methods that have an optional parameter
This has nothing to do with abstract classes. Method parameters are still bivariant so this type checks: see here
The typechecker considers it ok for the parameter in the parent to be less specific than the inheriting child, even though it is unsound.
It's by design because the sound alternative would be a significant inconvenience for array interfaces.
More on reddit.comVideos
I was surprised to see the Python abstract classes don't enforce anything except the override and method name. I can see why in Python enforcing parameter data-types would probably not work, but the number of parameters and parameter names ought to be enforced.
I've always thought the point of abstract classes was to ensure that any inheritor of the class would would work with existing code to run the abstract methods defined in the super class. The whole point was to enforce method signatures.
It seems to me that Python's implantation of abstract classes has very little utility. Does anyone even use them? What for?
Before abc was introduced you would see this frequently.
class Base(object):
def go(self):
raise NotImplementedError("Please Implement this method")
class Specialized(Base):
def go(self):
print "Consider me implemented"
Something along these lines, using ABC
import abc
class Shape(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def method_to_implement(self, input):
"""Method documentation"""
return
Also read this good tutorial: https://pymotw.com/3/abc/
You can also check out zope.interface which was used prior to introduction of ABC in python.
- http://pypi.python.org/pypi/zope.interface
- https://zopeinterface.readthedocs.io/en/latest/README.html