My Python application contains many abstract classes and implementations. For example:
import abc import datetime class MessageDisplay(object): __metaclass__ = abc.ABCMeta @abc.abstractproperty def display(self, message): pass class FriendlyMessageDisplay(MessageDisplay): def greet(self): hour = datetime.datetime.now().timetuple().tm_hour if hour < 7: raise Exception("Cannot greet while asleep.") elif hour < 12: self.display("Good morning!") elif hour < 18: self.display("Good afternoon!") elif hour < 20: self.display("Good evening!") else: self.display("Good night.") class FriendlyMessagePrinter(FriendlyMessageDisplay): def display(self, message): print(message)
FriendlyMessagePrinter
is a concrete class that we can use...
FriendlyMessagePrinter().greet()
Good night.
...but MessageDisplay
and FriendlyMessageDisplay
are abstract classes and attempting to instantiate one would result in an error:
TypeError: Can't instantiate abstract class MessageDisplay with abstract methods say
How can I check if a given class object is an (uninstantiatable) abstract class?
An abstract class can be considered as a blueprint for other classes. It allows you to create a set of methods that must be created within any child classes built from the abstract class. A class which contains one or more abstract methods is called an abstract class.
A concrete class which is a sub class of such abstract base class then implements the abstract base by overriding its abstract methods. The abc module defines ABCMeta class which is a metaclass for defining abstract base class. Following example defines Shape class as an abstract base class using ABCMeta.
In general, a class should be abstract when you have absolutely no reason to create an instance of that class. For example, suppose you have a Shape class that is the superclass of Triangle, Square, Circle, etc.
import inspect print(inspect.isabstract(object)) # False print(inspect.isabstract(MessageDisplay)) # True print(inspect.isabstract(FriendlyMessageDisplay)) # True print(inspect.isabstract(FriendlyMessagePrinter)) # False
This checks that the internal flag TPFLAGS_IS_ABSTRACT
is set in the class object, so it can't be fooled as easily as your implementation:
class Fake: __abstractmethods__ = 'bluh' print(is_abstract(Fake), inspect.isabstract(Fake)) # True, False
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