Classes are used to make objects. However, a class itself is an object and, just like any other object, it’s an instance of something: a metaclass.
A metaclass is the class of a class; it defines how a class behaves.
Hence, if we want to modify the behavior of classes, we will need to write our own custom metaclass.
The default metaclass is
This means that just like an object is of the type
class, a class itself is of the type,
class Foobar: pass foo = Foobar() print(type(foo)) print(type(Foobar))
Running the code extract above shows us that since
foo is an instantiation of the class
Foobar, its type is the class
Foobar. The class
Foobar, on the other hand, displays its own type as the class
type, which, as we earlier said, is the default metaclass.
type() function can be used to directly define classes by passing it through:
To create a custom metaclass, we first have to inherit the default metaclass,
type, and then override its
__init__() methods. The following code defines a metaclass with a custom
__new__() method which defines a new attribute
x in the class. The
Foo class inherits the attributes of its metaclass Meta:
class Meta(type): # overriding the new method of the metaclass def __new__(cls, name, bases, dct): x = super().__new__(cls, name, bases, dct) # defining that each class with th=is metaclass # should have a variable, x with a default value x.attr = 100 return x # defining a class with Meta as its metaclass instead # of type class Foo(metaclass = Meta): pass # printing the variables in our newly defined class print(Foo.attr)
Metaclasses can be applied in logging, registration of classes at creation time, profiling, and others. They propagate down the inheritance hierarchies, allowing all subclasses to inherit their attributes and methods. This property is particularly useful if we want our classes to have specific attributes, automatically, at the time of their creation.
View all Courses