Using Metaclasses and VBC
00:00
Metaclasses and Virtual Base Classes Ideally, you’d want the issubclass
check you saw earlier to return False
when the implementing class doesn’t define all of the interfaces abstract methods.
00:14
To do this, you can create a meta class called ParserMeta
. You’ll be overriding two dunder methods: __instancecheck__
, which is used by isinstance
and __subclasscheck__
, which is used by issubclass
.
00:30
Open up your editor and create a new file called meta
class py
. In the first part of the code, you create a ParserMeta
meta class and then a class called MetaclassInformal
‘ParserInterface that builds from
ParserMeta`.
01:03
There are two dunder methods defined here, but the __subclasscheck__
is the one where the interesting mechanism is put into play. It checks the class for the presence of the two callable attributes, load_data_source
and extract_text
.
01:17
If they’re present, then the class which has been submitted to the check will be considered a subclass of ParserMeta
. You’ll see this in action later on.
01:56
Now that ParserMeta
and MetaclassInformalParserInterface
have been created, you can create your concrete implementations. First, create a new class for passing PDFs.
02:21
Here, PdfParserMetaclass
overrides load_data_source
and extract_text
. So the __subclasscheck__
should return True
as it’s checking for the presence of these two methods.
02:35
Next, you have a new implementation of the EmlParser
.
02:58
By using a metaclass, you don’t need to explicitly define the subclasses. Instead, the subclass must define the required methods. If it doesn’t, then the issubclass
check will return False
. You can confirm this by importing the new classes and running the same tests as you did previously updated to reflect the new class names.
03:33
As expected, EmlParserMetaclass
fails the subclass test because it doesn’t define the extract_text
method. Now let’s take a look at the __mro__.
03:50
As you can see, MetaClassInformalParserInterface
is a superclass of PdfParserMetaclass
, but it doesn’t appear in the __mro__. This unusual behavior is caused by the fact that MetaClassInformalParserInterface
is a virtual base class of PdfParserMetaclass
.
04:10
In the previous example, the test seen on screen returned true even though MetaclassInformalParserInterface
didn’t appear in the PdfParserMetaclass
__mro__.
04:20
And that’s because it’s a virtual base class. The key difference between these and standard subclasses is that virtual base classes use the __subclasscheck__()
dunder method to implicitly check if a class is a virtual subclass of the superclass.
04:35
Additionally, virtual base classes don’t appear in the MRO. Create a new file called people.py
and add the code seen on screen.
05:08
Here, you have the setup for creating your virtual base classes. The metaclass PersonMeta
the base class PersonSuper
and the Python interface Person
.
05:36
With the setup for creating virtual base classes complete, you’ll define two concrete classes, Employee
and Friend
.
05:52
The Employee
class inherits from PersonSuper
while Friend
implicitly inherits from Person
.
06:08
Although Friend
doesn’t explicitly inherit from Person
, it implements name and age so Person
becomes a virtual base class of Friend
.
06:31
When you run issubclass (Friend, Person)
it returns True
, meaning that Friend
is a subclass of Person
.
06:41
The UML diagram seen on screen shows what happens when you call issubclass
on the Friend
class. Looking at PersonMeta
, you’ll notice there’s another method called __instance_check__
.
06:55
This method is used to check if instances of Friend
are created from the Person
interface. Your code calls __instance_check__
when you use isinstance (Friend, Person)
.
07:10 Informal interfaces can be useful for projects with a small code base and a limited number of programmers, but they’d be the wrong approach for larger applications so in the next section of the course, you’ll look at the solution for this problem–formal interfaces.
Become a Member to join the conversation.