TIL - In Python type() With Three Arguments Is a Dynamic Class Factory
type(name, bases, namespace) is how Python creates every class - the class keyword is syntax sugar for it. Calling it directly lets you generate classes programmatically at runtime.
# These two are exactly equivalent:
class Greeter:
greeting = "Hello"
def greet(self, name): return f"{self.greeting}, {name}!"
Greeter2 = type("Greeter2", (object,), {
"greeting": "Hello",
"greet": lambda self, name: f"{self.greeting}, {name}!"
})
print(Greeter2().greet("World")) # Hello, World!
# Dynamic subclassing — create an exception hierarchy at runtime
def make_error(name: str, base=Exception) -> type:
return type(name, (base,), {"__module__": __name__})
NotFoundError = make_error("NotFoundError")
ForbiddenError = make_error("ForbiddenError")
raise NotFoundError("item 42 not found")
This is the primitive that powers ORM field declarations, plugin systems, and serialization frameworks. Metaclasses are just subclasses of type that override __new__ or __init__ to hook into this process.