Implementing Formal Interfaces
00:00
Formal Interfaces. As you’ve seen, informal interfaces can be useful for smaller projects, but they would be the wrong approach for a larger application. In order to create a formal Python interface, you’ll need a few more tools from Python’s abc
module.
00:17
To enforce the subclass instantiation of abstract methods, you’ll utilize Python’s built-in ABCMeta from the abc
module, where abc
stands for abstract base classes.
00:30
Going back to the previous interface, you created your own metaclass, ParserMeta
with the overridden dunder methods, .__instancecheck__
and .__subclasscheck__
.
00:42
Rather than create your own metaclass, you’ll use abc.ABCMeta
as the metaclass. Then you’ll overwrite .__subclasshook__()
in place of .__instancecheck__()
and .__subclasscheck__
(), as it creates a more reliable implementation of these dunder methods.
01:01
On screen, you can see the implementation of FormalParserInterface
using abc.ABCMeta
as the metaclass.
02:35
If you run is_subclass
on PdfParserFormal
and EmlParserFormal
, then it will return True
and False
respectively as seen on screen.
02:55
Once you’ve imported the abc
module, you can directly register a virtual subclass by using the .register()
meta method. A good way to see this in action is to set up an example in the REPL for immediate results.
03:20
Here, you register the interface Double
as a virtual base class of the built-in float
class.
03:31
By using the .register()
meta method you’ve successfully registered Double
as a virtual subclass of float
and once registered, you can use it as a class decorator to set the decorated class as a virtual subclass.
03:51
The decorator .register()
method helps you to create a hierarchy of custom virtual class inheritance. You must be careful when you are combining .__subclasshook__
with .register()
as .__subclasshook__
takes precedence over virtual subclass registration. To ensure that the registered virtual subclasses are taken into consideration, you must add NotImplemented
to the .__subclasshook__
method.
04:20 You can see this update on screen
04:31
Next, the registration decorator is added to the EmlParser
concrete class.
04:44
You can test this new code in the same way you saw for the previous implementation using issubclass
.
04:59
Since you’ve used registration, you can see that the EmlParser
concrete class is considered a virtual subclass of the FormalParserInterface
.
05:09
This isn’t what you wanted as it doesn’t override extract_text
, so please make sure you use caution with virtual subclass registration. An abstract method is a method that’s declared by the Python interface, but it may not have a useful implementation.
05:28
This abstract method must be overridden by the concrete class that implements the interface in question. To create abstract methods in Python, you add the abc.abstractmethod
decorator to the interface’s methods.
05:43
Start with the original code from formal.py
and make the modifications seen on screen to update the FormalParserInterface
to include the abstract methods, load_data_source
, and extract_text
.
06:38 Here you’ve created a formal interface that will raise errors when the abstract methods are not overridden by concrete classes.
07:02
The pdf_parser
formal instance, PdfParser
won’t raise any errors as PdfParserFormal
is correctly overriding the FormalParserInterface
abstract methods. Attempting to create the EmlParser
FormalInstance
raises an error.
07:20 As you can see, the traceback message tells you that you haven’t overridden all the abstract methods, and this is the behavior you would expect when building a formal Python interface.
07:32 In the next section of the course, you’ll round out your knowledge of interfaces by seeing implementations in some other languages.
Become a Member to join the conversation.