PEP 3119 states that:
The
@abstractmethod
decorator should only be used inside a class body, and only for classes whose metaclass is (derived from)ABCMeta
. Dynamically adding abstract methods to a class, or attempting to modify the abstraction status of a method or class once it is created, are not supported.
I cannot find, however, an explanation of why that is. Specifically, I do not notice a difference in behavior when using only @abstractmethod
in a class that does not explicitly inherit from ABCMeta
. In the following simple example, if I understand correctly, the proper way of doing things would be:
import six
from abc import ABCMeta
from abc import abstractmethod
class Base(six.with_metaclass(ABCMeta)):
def __init__(self):
print('Init abstract base')
@abstractmethod
def do_something(self):
pass
class Subclass(Base):
def __init__(self):
super(Subclass, self).__init__()
def do_something(self):
print('Done.')
sub = Subclass()
sub.do_something()
However, if I let the Base
class inherit simply from object
, and only use the decorator when needed, I notice no change in behavior.
from abc import abstractmethod
class Base(object):
def __init__(self):
print('Init abstract base')
@abstractmethod
def do_something(self):
pass
class Subclass(Base):
def __init__(self):
super(Subclass, self).__init__()
def do_something(self):
print('Done.')
sub = Subclass()
sub.do_something()
I have found this to be the case even on more complex architectures, so I wonder: when does the latter method fail?
ABCMeta metaclass provides a method called register method that can be invoked by its instance. By using this register method, any abstract base class can become an ancestor of any arbitrary concrete class.
An abstract class in Python is typically created to declare a set of methods that must be created in any child class built on top of this abstract class. Similarly, an abstract method is one that doesn't have any implementation.
ABCMeta . i.e abc. ABC implicitly defines the metaclass for us. The only difference is that in the former case you need a simple inheritance and in the latter you need to specify the metaclass.
The 'abc' module in the Python library provides the infrastructure for defining custom abstract base classes. Abstract class cannot be instantiated in python. An Abstract method can be call by its subclasses.
You don't see any difference because your first subclass does implement the do_something
abstractmethod.
Comment out the definition of do_something
in the subclasses in both versions and you'll find out that in the first case you get a TypeError
when trying to instanciate the subclass - you'd also get one trying to instanciate the first version Base
class itself FWIW. With the second version, you can instanciate both classes (which shouldn't be possible since they are abstract) and call the abstract do_something
method - which kind of defeats one of main points of ABCs.
You'll also miss quite a few other interesting features of ABCs FWIW...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With