You can use __init_subclass__
(which was intended to provide metaclass-like functionality via simple inheritance).
class Parent:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
if not hasattr(cls, 'property'):
raise TypeError("Subclass must define class attribute 'property'")
class ChildThatWorks(Parent):
property = 3
class ChildThatFails(Parent):
pass
An interesting option is to pass property
as an keyword argument, rather than an assignment in the body of the class statement.
class Parent:
def __init_subclass__(cls, *, property, **kwargs):
setattr(cls, 'property', property)
class ChildThatWorks(Parent, property=3):
pass
class ChildThatFails(Parent):
pass
ChildThatFails
will produce the following traceback:
Traceback (most recent call last):
File "/Users/chepner/tmp.py", line 8, in <module>
class ChildThatFails(Parent):
TypeError: __init_subclass__() missing 1 required keyword-only argument: 'property'
The code is simpler, but you have less flexibility in how you handle the failure to provide the property
value.