Python
Metaprogramming
Write a DSL with metaclass and descriptors.
The metaprogramming layer
In this lesson you will add a Field descriptor and a ModelMeta metaclass alongside the Tool class. Field learns its name via __set_name__; ModelMeta manages class creation.
The Model class is defined with metaclass=ModelMeta and contains ad = Field(). The Field's __set_name__ method adds the field name to Model.fields. This is the basis of declarative field definition and will be used for parallel processing in later lessons.
Exercise Add Field and ModelMeta
The starting code already has the Tool class. Now write a Field descriptor class: in __set_name__(self, owner, name) set self.name = name, create owner.fields = [] if missing and append name. Write a ModelMeta(type) metaclass whose __new__ returns super().__new__. In Model(metaclass=ModelMeta) define ad = Field(). Print Model.fields.
Show example solution
# Build the Tool class with type()
Tool = type("Tool", (), {
"name": "arac",
"run": lambda self: f"{self.name} calisti",
})
# Add Field descriptor and ModelMeta
class Field:
def __set_name__(self, owner, name):
self.name = name
if not hasattr(owner, "fields"):
owner.fields = []
owner.fields.append(name)
class ModelMeta(type):
def __new__(mcs, name, bases, ns):
return super().__new__(mcs, name, bases, ns)
class Model(metaclass=ModelMeta):
ad = Field()
print(Model.fields)
Next step: multiprocessing
Field and ModelMeta are ready. In the next lesson you will add a parallel processing layer: square computation with multiprocessing.Pool.
This layer will process data with parallel processes. Each lesson adds a layer and the starting code carries the previous solution. So far the Tool, Field and ModelMeta layers are ready.
Test yourself
-
Match metaprogramming concepts
- Field
- Descriptor
- ModelMeta
- Metaclass
- __set_name__
- Name notification
- Model.fields
- Field list
-
What does the Field descriptor do?
- Records the field name
- Loads a C library
- Starts a process
- Computes an array
Show answer
Records the field name — Field records the field name into Model.fields via __set_name__.
-
Complete the ModelMeta definition
class ModelMeta(____):
def __new__(mcs, name, bases, ns):
return super().__new__(mcs, name, bases, ns)
Show answer
class ModelMeta(type):
def __new__(mcs, name, bases, ns):
return super().__new__(mcs, name, bases, ns)
Next lesson: Multiprocessing