Essentially what I want is to require that subclasses of an abstract base classes not only implement certain attributes or methods, but can also make requirements on those, such as data types or allowed values.
For example, let's say I want to require classes that have a name
and that that name
starts with the letter 'a':
from abc import ABC, abstractproperty
class Base(ABC):
@abstractproperty
def name(self):
assert self.name[0] == 'a' # or similar; help needed here
class Derived1(Base):
name = 'albert' # I want this class definition to work
class Derived2(Base):
name = 'john' # I want this class definition to fail the 'a' assertion
Where/how would I assert this in the base class?
Use __init_subclass__
to enforce restrictions on class attributes.
class Base:
def __init_subclass__(cls):
try:
name = cls.name
except AttributeError:
raise ValueError("No name attribute")
if name[0] != "a":
raise ValueError("first letter of name is not 'a'")
class Derived1(Base):
name = 'albert' # OK
class Derived2(Base):
name = 'john' # Fails due to first letter 'j'
# Fails because Derived3.name is never defined
class Derived3(Base):
pass