class ABC
is an "abstract base class". class X
is its subclass.
There's some work that needs to be done in any subclass of ABC
, which is easy to forget or do incorrectly. I'd like ABC.__init__()
to help catch such mistakes by either:
(1) starting that work, or (2) validating it
This impacts whether super().__init__()
is called at the start or at the end of X.__init__()
.
Here's a simplified example for illustration purposes:
Suppose every subclass of ABC
must have an attribute registry
, and it must be a list. ABC.__init__()
can either (1) initialize registry
or (2) check that it was properly created. Following is the sample code for each approach.
Approach 1: initialize in ABC
class ABC:
def __init__(self):
self.registry = []
class X:
def __init__(self):
super().__init__()
# populate self.registry here
...
Approach 2: validate in ABC
class ABC:
class InitializationFailure(Exception):
pass
def __init__(self):
try:
if not isinstance(self.registry, list):
raise ABC.InitializationError()
except AttributeError:
raise ABC.InitializationError()
class X:
def __init__(self):
self.registry = []
# populate self.registry here
...
super().__init__()
Which is a better design?
registry
being a list, when I populate it in the subclass, correct? That is, rather than useregistry.append(new_item)
andregistry[-1] = new_item
freely, I should try and useself.add_to_registry(new_item)
, which will be defined in ABC to.append()
, but could be changed to.add()
later if needed? – Hemihydrate