I would override __new__()
in the base class and simply fail to instantiate at all if it’s the base class.
class BaseClass: # Py3
def __new__(cls, *args, **kwargs):
if cls is BaseClass:
raise TypeError(f"only children of '{cls.__name__}' may be instantiated")
return object.__new__(cls, *args, **kwargs)
This separates concerns a little better than having it in __init__()
, and “fails fast.”