Python
Summary - Metaprogramming
Combine type, metaclass and __init_subclass__ to write a DSL.
Recap: metaprogramming tools
In this group you learned four tools. type() for dynamic classes, metaclass to intercept class creation, __init_subclass__ as a lightweight hook, __class_getitem__ for subscripting, @decorator to wrap a class.
Now you will combine them into a mini DSL: a Field descriptor and a ModelMeta metaclass. Field learns its name via __set_name__; the metaclass collects fields into a fields list. This is the core idea behind Django and SQLAlchemy.
Exercise Mini DSL: Field + metaclass
Write a Field class with a __set_name__(self, owner, name) method; it sets self.name = name, creates owner.fields = [] if missing and appends name. Write a ModelMeta(type) metaclass whose __new__ returns super().__new__. In User(metaclass=ModelMeta) define name = Field(). Print User.fields.
Show example solution
# Write 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 User(metaclass=ModelMeta):
name = Field()
print(User.fields)
What you learned
In this group you went deep into Python's class creation mechanism. You learned to build a class by hand with type(), intercept the process with a metaclass, and write lightweight hooks with __init_subclass__.
You also saw __class_getitem__ for generic-looking APIs and @decorator to add behavior after the fact. In the summary you combined these into a mini DSL: a Field descriptor + metaclass. This pattern is the backbone of major Python frameworks.
Test yourself
-
Which tool for which job?
- type() for dynamic classes
- __init_subclass__ for subclass hooks
- metaclass to create instances
- @decorator to wrap a class
Show answer
@decorator to wrap a class — @decorator wraps a class; creating instances is __init__'s job.
-
Match all metaprogramming concepts
- type()
- Dynamic class
- metaclass
- Class production
- __init_subclass__
- Subclass hook
- @decorator
- Class wrapping
-
Final blank
class ModelMeta(type):
def __new__(mcs, name, bases, ns):
return super().____(mcs, name, bases, ns)
Show answer
class ModelMeta(type):
def __new__(mcs, name, bases, ns):
return super().__new__(mcs, name, bases, ns)
Next lesson: Descriptor protocol