Is there a convenient way to enforce a method's input and output invariants, when the method is overridden in a subclass?
By enforcing invariants, I mean checking things like:
- The number of input arguments
- The types of some/all of the inputs
- The number of output arguments
- The types of some/all of the outputs
(Related questions have asked about enforcing the # of input arguments, but not the types. Others have asserted that explicit type checking is unpythonic, but, well, in this instance I don't care.)
For example, I have a base class B, with a method to be subclassed that takes an int and returns a float.
class B(object):
def returns_float(self, int_arg):
raise NotImplementedException("implement me")
To enforce this int->float signature, I currently split the method into returns_float()
, and its implementation, _returns_float()
. The subclass overrides the latter.
class B(object):
def returns_float(self, int_arg):
if not numpy.issubdtype(int_arg, 'int'):
raise TypeError("Arg isn't an int.")
result = self._returns_float(int_arg)
if not numpy.issubdtype(result, 'float64'):
raise TypeError("Return type isn't a float64")
return result
def _returns_float(self, int_arg):
raise NotImplementedException("implement me")
This is flexible and explicit, but I'm wondering if there's some slicker way to do this?