A metaclass is a class of a class that defines how classes behave. Metaclasses are an advanced and powerful feature that allows you to customize the creation and behavior of classes themselves. Normally, when you create a class in Python, the type
metaclass is used behind the scenes to create the class object. However, by defining your own metaclass, you can intercept and modify the process of class creation.
Metaclasses are particularly useful when you need to enforce certain patterns, add attributes or methods automatically, or modify class behavior globally across a codebase.
Let’s explore a basic example of using a metaclass to customize class creation by adding an attribute to every class that uses the metaclass.
# Defining a custom metaclass
class MyMeta(type):
def __new__(cls, name, bases, class_dict):
print(f"Creating class {name}")
class_dict['custom_attribute'] = 'Hello, World!'
return super().__new__(cls, name, bases, class_dict)
# Using the custom metaclass to create a class
class MyClass(metaclass=MyMeta):
pass
# Instantiating the class
obj = MyClass()
print(obj.custom_attribute) # Outputs: Hello, World!
class MyMeta(type):
def __new__(cls, name, bases, class_dict):
print(f"Creating class {name}")
class_dict['custom_attribute'] = 'Hello, World!'
return super().__new__(cls, name, bases, class_dict)
MyMeta
Class: Here, we define a metaclass named MyMeta
that inherits from type
. The type
class is the default metaclass in Python, and by subclassing it, we can override its behavior.__new__
Method: The __new__
method is a special method responsible for creating a new class. It is called before __init__
and is typically used to customize the creation process of new objects or, in this case, new classes.
cls
: The metaclass itself.name
: The name of the class being created.bases
: A tuple of base classes that the new class will inherit from.class_dict
: A dictionary containing the class’s attributes and methods.custom_attribute
to the class dictionary with the value "Hello, World!"
.__new__
method calls super().__new__
to actually create the class using the default behavior, but with our custom modifications applied.class MyClass(metaclass=MyMeta):
pass
MyClass
Definition: Here, we define a new class MyClass
and specify that it should use MyMeta
as its metaclass by setting metaclass=MyMeta
. When Python encounters this, it uses the MyMeta
metaclass to create MyClass
instead of the default type
.MyClass
class is defined, the __new__
method in MyMeta
is called. The method prints “Creating class MyClass” and adds custom_attribute
to MyClass
.obj = MyClass()
MyClass
, Python follows the usual object instantiation process. However, the class itself has already been customized by the metaclass, so obj
now has access to any attributes or methods added by the metaclass.print(obj.custom_attribute) # Outputs: Hello, World!
custom_attribute
was added to MyClass
by the metaclass during class creation, obj
, an instance of MyClass
, can access this attribute. The output will be "Hello, World!"
.__new__
in a metaclass, you can inject custom behavior during the class creation process, such as automatically adding attributes or methods to classes.