ReviseAlgo Logo

Advanced Topics

Metaprogramming

Code that generates or manipulates code at runtime

Interview: Advanced Python — frequently probed in senior roles

Last Updated: June 12, 2026 10 min read

Metaprogramming is the technique of writing code that inspects, generates, or modifies other code at runtime. Python provides two primary mechanisms: decorators (function/class wrappers) and metaclasses (classes that create classes).

Decorators Recap

Decorators are the most common form of metaprogramming. They wrap a function or class to extend its behavior without modifying the original source code.

A decorator is simply a callable that takes a function and returns a new function. The @decorator syntax is sugar for func = decorator(func).

Metaclasses

A metaclass is the "class of a class." Just as an object is an instance of a class, a class is an instance of a metaclass. The default metaclass is type.

When you write class Foo: pass, Python internally calls type('Foo', (), {}) to create the class object. By supplying a custom metaclass, you intercept this creation step.

When to Use Metaclasses

Most applications never need metaclasses. Prefer __init_subclass__ (Python 3.6+) or class decorators for simpler use cases. Metaclasses shine in framework development (ORMs, serialization libraries) where you need to enforce rules across an entire class hierarchy.

The Descriptor Protocol

Descriptors are objects that define __get__, __set__, and/or __delete__. They power Python's attribute access mechanism and are the foundation of @property, @classmethod, and @staticmethod.

Common Pitfalls

  • Over-engineering: Don't use a metaclass when a decorator or __init_subclass__ suffices.
  • Multiple metaclass conflicts: If class A has metaclass MA and class B has metaclass MB, a class inheriting both will raise TypeError.
  • Debugging difficulty: Metaclass logic runs at class creation time, making stack traces confusing.

Use Cases

Plugin/Extension frameworks with auto-registration

ORM model field definitions (Django, SQLAlchemy)

API validation and serialization libraries

Enforcing coding standards across a class hierarchy

Common Mistakes

Using metaclasses when __init_subclass__ or class decorators suffice

Forgetting functools.wraps on decorators — breaks introspection and debugging

Multiple metaclass inheritance causing TypeError conflicts

Not understanding the MRO (Method Resolution Order) when combining metaclasses