Python - Parameter checking with Exception Raising
You could create a decorator function and pass the expected types and (optional) ranges as parameters. Something like this:
def typecheck(types, ranges=None):
def __f(f):
def _f(*args, **kwargs):
for a, t in zip(args, types):
if not isinstance(a, t):
raise TypeError("Expected %s got %r" % (t, a))
for a, r in zip(args, ranges or []):
if r and not r[0] <= a <= r[1]:
raise ValueError("Should be in range %r: %r" % (r, a))
return f(*args, **kwargs)
return _f
return __f
Instead of if ...: raise
you could also invert the conditions and use assert
, but as noted in comments those might not always be executed.
You could also extend this to allow e.g. open ranges (like (0., None)
) or to accept arbitrary (lambda
) functions for more specific checks.
Example:
@typecheck(types=[int, float, str], ranges=[None, (0.0, 1.0), ("a", "f")])
def foo(x, y, z):
print("called foo with ", x, y, z)
foo(10, .5, "b") # called foo with 10 0.5 b
foo([1,2,3], .5, "b") # TypeError: Expected <class 'int'>, got [1, 2, 3]
foo(1, 2.,"e") # ValueError: Should be in range (0.0, 1.0): 2.0