What are metaclasses in Python, and how can they be used?

Austin Jorgensen
2 min readMar 22, 2023

--

An image with the text “What are metaclasses in Python?”.

Metaclasses in Python are a powerful and advanced feature that allow you to control the creation and behavior of classes themselves. In simple terms, a metaclass is a class whose instances are themselves classes. By defining a metaclass, you can customize the way classes are created, modify their behavior, and impose constraints on them.

The default metaclass in Python is type, which is responsible for creating classes when you define them using the class keyword. You can create your own metaclass by subclassing type and overriding its methods, such as __new__ or __init__.

Here’s how you can create and use a metaclass:

# Define the metaclass by subclassing type
class MyMeta(type):
def __new__(cls, name, bases, dct):
# Perform custom actions or validations here
return super().__new__(cls, name, bases, dct)

# Use the metaclass in a class definition
class MyClass(metaclass=MyMeta):
pass

By using a metaclass, you can achieve various tasks such as:

  • Enforcing coding standards or naming conventions
  • Automatic registration of classes (e.g., for plugins)
  • Singleton pattern implementation
  • Attribute validation or modification
  • Class structure validation

Here’s an example of a metaclass that enforces all methods in a class to have a docstring:

class DocstringMeta(type):
def __new__(cls, name, bases, dct):
for attr_name, attr_value in dct.items():
if callable(attr_value) and not attr_name.startswith('__'):
if attr_value.__doc__ is None:
raise ValueError(f'Method {name}.{attr_name} must have a docstring')
return super().__new__(cls, name, bases, dct)

class MyClass(metaclass=DocstringMeta):
def my_method(self):
"""This method has a docstring, so it's okay."""
pass

def another_method(self):
pass # This will raise an error because it lacks a docstring

While metaclasses are powerful, they can also make code more complex and harder to understand, so use them judiciously. They are most appropriate for cases where the added functionality or constraints can’t be achieved through simpler techniques like class decorators or inheritance.

--

--

Austin Jorgensen

Topics of Interest: Python, JavaScript, Node.js, AI, ML, Health and Wellness.