The term metaprogramming refers to the potential for a program to have knowledge of or manipulate itself. Python supports a form of metaprogramming for classes called metaclasses.
Metaclasses are an esoteric OOP concept, lurking behind virtually all Python code. You are using them whether you are aware of it or not. For the most part, you don’t need to be aware of it. Most Python programmers rarely, if ever, have to think about metaclasses.
When the need arises, however, Python provides a capability that not all object-oriented languages support: you can get under the hood and define custom metaclasses. The use of custom metaclasses is somewhat controversial, as suggested by the following quote from Tim Peters, the Python guru who authored the Zen of Python:
“Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t (the people who actually need them know with certainty that they need them, and don’t need an explanation about why).”
— Tim Peters
There are Pythonistas (as Python aficionados are known) who believe that you should never use custom metaclasses. That might be going a bit far, but it is probably true that custom metaclasses mostly aren’t necessary. If it isn’t pretty obvious that a problem calls for them, then it will probably be cleaner and more readable if solved in a simpler way.
Still, understanding Python metaclasses is worthwhile, because it leads to a better understanding of the internals of Python classes in general. You never know: you may one day find yourself in one of those situations where you just know that a custom metaclass is what you want.
Get Notified: Don’t miss the follow up to this tutorial—Click here to join the Real Python Newsletter and you’ll know when the next installment comes out.
Take the Quiz: Test your knowledge with our interactive “Python Metaclasses” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
Python MetaclassesCheck how well you understand Python metaclasses, from what they are and how type creates classes to when a custom metaclass is actually the right tool.
Intermediate Python Deep Dive Live Course: Want to understand how classes, objects, and types fit together in Python’s object model? Real Python’s Intermediate Python Deep Dive live course explores the object model, special methods, and decorators with an instructor and a small cohort. Join the waitlist to hear about the next dates.
Old-Style vs. New-Style Classes
In the Python realm, a class can be one of two varieties. No official terminology has been decided on, so they are informally referred to as old-style and new-style classes.
Old-Style Classes
With old-style classes, class and type are not quite the same thing. An instance of an old-style class is always implemented from a single built-in type called instance. If obj is an instance of an old-style class, obj.__class__ designates the class, but type(obj) is always instance. The following example is taken from Python 2.7:
>>> class Foo: ... pass ... >>> x = Foo() >>> x.__class__ <class __main__.Foo at 0x000000000535CC48> >>> type(x) <type 'instance'> New-Style Classes
New-style classes unify the concepts of class and type. If obj is an instance of a new-style class, type(obj) is the same as obj.__class__:
>>> class Foo: ... pass ... >>> obj = Foo() >>> obj.__class__ <class '__main__.Foo'> >>> type(obj) <class '__main__.Foo'> >>> obj.__class__ is type(obj) True >>> n = 5 >>> d = { 'x' : 1, 'y' : 2 } >>> class Foo: ... pass ... >>> x = Foo() >>> for obj in (n, d, x): ... print(type(obj) is obj.__class__) ... True True True Type and Class
In Python 3, all classes are new-style classes. Thus, in Python 3 it is reasonable to refer to an object’s type and its class interchangeably.
Note: In Python 2, classes are old-style by default. Prior to Python 2.2, new-style classes weren’t supported at all. From Python 2.2 onward, they can be created but must be explicitly declared as new-style.
Remember that, in Python, everything is an object. Classes are objects as well. As a result, a class must have a type. What is the type of a class?
Consider the following:
>>> class Foo: ... pass ... >>> x = Foo() >>> type(x) <class '__main__.Foo'> >>> type(Foo) <class 'type'> Read the full article at https://realpython.com/python-metaclasses/ »
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
