Alex Rivera | Logout

python: abstract base class' __init__(): initializion or validation?

Asked 2011-02-27T12:43:41.807
17

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?

Edit
Report

1 Answer

2

In the example you have provided, I would do it as in your approach 1. I would see class ABC mainly as an implementation helper for X and other classes that implement a certain interface, however. Said interface consists of the attribute 'registry'.

You should, logically at least, discern between the interface shared by X and other classes, and the baseclass which helps you implement it. That is, define separately that there is an interface (for example "ABC"), which exposes a list "registry". Then, you may decide to factor out the implementation of the interface as a common baseclass (conceptually a mix-in) to implementors of interface ABC, since it makes it very easy to introduce new implementing classes (in addition to X).

Edit: With regard to guarding against mistakes in implementing classes, I'd target this through unit tests. I think this is more comprehensive than trying to account for everything in your implementation :)

answered 2011-02-27T13:49:45.993

Your Answer