Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

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.