Use metaclasses
#In-depth analysis of Python metaclass
Have you ever been curious about Python’sclassWhat exactly is done behind the keywords? Why are Python's class definitions so much more "flexible" than static languages such as Java and C++? Today we will dig deeper into Python's advanced features - metaclass, and together we will uncover the mystery of dynamically creating classes and even controlling the class creation process.
Dynamic types andtype()function
Python is a purely dynamic language: its classes and functions are not templates that are hard-coded during the compilation phase, but objects that are dynamically generated when the program is running. This point is a core premise for understanding metaclasses.
type()two identities
Many people only knowtype()It can "view the type of object", but its true identity is actually the default "class factory" for all classes in Python - that is, the default metaclass.
1. Basic usage: View type
Note: the types of all classes aretype! This implies that "classes are also created from another thing (type)."
2. Core usage: dynamically create classes
If not usedclasskeyword, we can call it manuallytype()To generate a fully functional class:
In-depth understanding of metaclass
Since the class is composed oftypeCreated, then if we want to customize the "class creation rules" (for example: automatically add a method to all subclasses, modify the class name, filter attributes), we need to use the "custom metaclass".
Three-layer relationship chain
In order to avoid confusing levels, we first remember this core chain:
Use a life-like metaphor to explain:
- Custom metaclass = "Mold Factory" (specifies the standards for "production of molds")
- General type = "Mold" (produced according to the standards of the mold factory and used to generate products)
- Instance = "Product" (generated by mold)
How to write custom metaclasses
Custom metaclasses must meet two conditions:
- Inherited from default metaclass
type - Naming convention (not mandatory but recommended) begins with
Metaclassending
Usually we will override the metaclass__new__Method - This is the interception entry of the class creation process. The parameters are as follows:
cls: The "metaclass instance" currently being created (that is, the ordinary class itself)name: Common class name to be generatedbases: Tuple of parent classes inherited by ordinary classesattrs: Dictionary of attributes and methods of ordinary classes
Small example: automatically add to the listaddmethod
Python nativelistonlyappendmethod, noadd. We can use a metaclass to automatically have it for all list classes that inherit itadd:
Practical application: handwriting a minimalist ORM framework
One of the most classic and practical scenarios of metaclasses is ORM (Object-Relational Mapping) - completely mapping database tables, fields, and records into Python classes, attributes, and instances, allowing developers to operate the database without writing SQL.
Step 1: Define field mapping class
First write a few basic classes to represent "database fields":
Step 2: Use metaclasses to process model classes
Next, write the coreModelMetaclass. It needs to be in the model class (e.g.User) complete the following tasks when creating:
- Skip the base class
Modelitself (only handles specific business table classes) - Collect all objects defined in the class
FieldExample - Put these
FieldRemoved from class attributes (to prevent instance attributes from being overridden by class attributes) - Save field mapping and table name to class attributes
Step 3: Define ORM base class
write lastModelBase class, which requires:
- Inherited from
dict(Convenient to use dictionary to store data) - Implementation
__getattr__and__setattr__(Let the instance access properties like a normal object) - Implement common database operation methods (such as
save())
Step 4: Actual use of ORM
Now, we can define the database table just like a normal class:
The output of running this code is as follows:
Summarize
type()Dual identity: It is both a tool for "viewing object types" and the default metaclass for all classes in Python.- The role of metaclass: intercept the creation process of classes and realize the requirements of "batch customization of classes" (such as ORM, Django's Admin system, etc.).
- Use with caution: Metaclasses are one of the most powerful features of Python, but in 99% of scenarios the problem can be solved with ordinary methods (such as decorators and inheritance). Misuse of metaclasses can make code difficult to understand and maintain.
Although there is a certain threshold for understanding metaclasses, it can help you gain a deeper grasp of Python's object-oriented mechanism, giving you one more handy tool when encountering scenarios that require "designing the class itself."

