Metaclasses in Python (Summary)
Magicians aren’t supposed to reveal their secrets, but understanding metaclasses allows you to unravel the mystery for yourself. In this course, you’ve discovered the secret to several of Python’s greatest tricks, from class instantiation and object-relational mapping (ORM) models to Enum
.
It’s worth noting that it isn’t typically necessary to create custom metaclasses. If you can solve the problem at hand in a simpler way, then you probably should. Still, it’s beneficial to understand metaclasses so that you understand Python classes in general and can recognize when a metaclass really is the appropriate tool to use.
Further Investigation:
- New-style classes
- Mike Fletcher’s slideshow on metaclasses
- PEP 3115: Metaclasses in Python 3000
- Build Enumerations of Constants With Python’s Enum
Congratulations, you made it to the end of the course! What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment in the discussion section and let us know.
00:00
In the previous lesson, I gave a high-level overview of the standard library’s Enum
class and how it uses the EnumType
metaclass to do its attribute magic.
00:10 In this final lesson, I’ll summarize the course and point you at some further investigation.
00:16
Everything in Python is an object, even the classes responsible for defining objects. Python 2.2 introduced a new style of class definition that uses the type
metaclass as its base. In Python 2, you use this new style by explicitly inheriting from obj
, while in Python 3, this is implicit. Whether or not you inherit from obj
, you get the same new-style class.
00:43
The type()
function can be used to dynamically create classes, and when you invoke a class, it instantiates an object of that class. You saw how invocation is generally done with a .__call__()
method, and in the case of object instantiation, the object’s .__new__()
and .__init__()
methods get called.
01:05
You can override an object’s .__new__()
, but you can’t do that to type
’s. If you want to change how classes get instantiated, instead of hooking type
’s .__new__()
, you use a metaclass.
01:16
This is done through the metaclass
argument in the inheritance declaration of a class. Metaclasses inherit from the type
type, and their methods get called at class creation. The .__prepare__()
method of a metaclass is a hook, so you can play with the class’s attribute dictionary. And .__new__()
is used to do the actual class creation.
01:39 This is the most common place to hook, allowing you to perform side effects when a class is created. This means you can do things like singletons or other activities that you might otherwise have to do in a factory function.
01:53 This Python docs page is a collection of links to places talking about the “new”—in air quotes—class hierarchy. On that page, you’ll find a link to Mike Fletcher’s slideshow on metaclasses, where you can see most of what I’ve shown you as well as some other examples. And finally, why not go back to the source of all this?
02:13 PEP 3115 is what defined how metaclasses would work in Python 3.
02:21 Metaclasses should be used sparingly, but can provide you with tools not available in a lot of languages. They can be a bit hairy at times, but that’s part of the fun.
02:31 Thanks for your attention. I hope you enjoyed the course.
Become a Member to join the conversation.