Abstract methods in Python [duplicate]
I am having trouble in using inheritance with Python. While the concept seems too easy for me in Java yet up till now I have been unable to understand in Python which is surprising to me at least.
I have a prototype which follow:
class Shape():
def __init__(self, shape_name):
self.shape = shape_name
class Rectangle(Shape):
def __init__(self, name):
self.shape = name
In the above code how can I make an abstract method that would need to be implemented for all the subclasses?
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
See the abc module. Basically, you define __metaclass__ = abc.ABCMeta
on the class, then decorate each abstract method with @abc.abstractmethod
. Classes derived from this class cannot then be instantiated unless all abstract methods have been overridden.
If your class is already using a metaclass, derive it from ABCMeta
rather than type
and you can continue to use your own metaclass.
A cheap alternative (and the best practice before the abc
module was introduced) would be to have all your abstract methods just raise an exception (NotImplementedError
is a good one) so that classes derived from it would have to override that method to be useful.
However, the abc
solution is better because it keeps such classes from being instantiated at all (i.e., it "fails faster"), and also because you can provide a default or base implementation of each method that can be reached using the super()
function in derived classes.