Python __init_subclass__ and Class Creation Hooks
Learn how Python bases can configure, validate, and register subclasses with __init_subclass__.
Intermediate
Python gives a class a hook named __init_subclass__ that runs when a subclass is created. It lets a base class configure or validate future subclasses without requiring a custom metaclass.
Run code when a subclass is created
Define __init_subclass__ on a base class to run code whenever a direct or indirect subclass is created. The cls parameter refers to the new subclass, not to the base class that defines the hook.
|
|
Creating Report calls Base.__init_subclass__ with Report as cls.
The hook receives the new class
__init_subclass__ is defined like a normal method, but Python arranges for it to behave as a class method during subclass creation. Use cls to inspect or configure the new subclass.
|
|
The hook adds a class attribute to the newly created subclass.
Accept class-definition options
A class definition can pass keyword arguments that a base class's __init_subclass__ accepts. This is useful when subclasses declare small pieces of configuration next to their class header.
|
|
kind is supplied in the subclass header and stored on the new class.
Forward unused keywords with super()
A cooperative __init_subclass__ should consume the keywords it owns and forward the rest to super().__init_subclass__. This lets multiple classes participate in subclass customization without each class having to know every option.
|
|
Named consumes label and forwards any remaining subclass keywords.
Validate subclasses at definition time
Because the hook runs while the subclass is created, it can reject an invalid subclass immediately. Raising an exception stops that class definition from succeeding.
|
|
Start is created successfully because it defines the required run method.
Build a small subclass registry
A base class can use __init_subclass__ to register each new subclass. The registry is just ordinary class data; the hook supplies the moment when a subclass enters it.
|
|
Each subclass is added to Handler.registry when its class definition completes.
Subclasses of subclasses also trigger the inherited hook
A subclass inherits __init_subclass__ unless it overrides it, so creating a deeper subclass can trigger the hook again. The cls value identifies the newly created class each time.
|
|
The inherited hook records both First and its subclass Second.
Know where __init_subclass__ fits
__init_subclass__ is a class-creation hook for configuring future subclasses. It is different from a class decorator, which transforms one particular class after it is created, and from a metaclass, which controls the class-creation machinery itself.
Keep the hook small and explicit: consume the options your base class owns, pass unrelated options to super().__init_subclass__, and let the subclass definition remain readable.
Key takeaways
- __init_subclass__ runs when a subclass is created, and cls is the new subclass.
- A base class can configure, validate, or register subclasses through the hook.
- Subclass keyword arguments can configure the hook; cooperative hooks should forward unused keywords with super().
- __init_subclass__ is a lighter class-creation customization mechanism than a custom metaclass.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.