CodeBlanks Logo Icon CodeBlanks

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.

Practice 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.

Starter code

main.py
# Write Field descriptor and ModelMeta
# use Field in the User class
# print the field names

Sample solution

main.py
# 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)

Expected output

['name']

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.

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Which tool for which job?

  • type() for dynamic classes
  • __init_subclass__ for subclass hooks
  • metaclass to create instances
  • @decorator to wrap a class Correct answer

Explanation: @decorator wraps a class; creating instances is __init__'s job.

2 Match all metaprogramming concepts

Term Meaning
type() Dynamic class
metaclass Class production
__init_subclass__ Subclass hook
@decorator Class wrapping

3 Final blank

Question
class ModelMeta(type):
    def __new__(mcs, name, bases, ns):
        return super().____(mcs, name, bases, ns)
Answer
class ModelMeta(type):
    def __new__(mcs, name, bases, ns):
        return super().__new__(mcs, name, bases, ns)

Explanation: super().__new__ produces the actual class object.

All lessons in Expert