I know, type checking function arguments is generally frowned upon in Python, but I think I've come up with a situation where it makes sense to do so.
In my project I have an Abstract Base Class Coord
, with a subclass Vector
, which has more features like rotation, changing magnitude, etc. Lists and tuples of numbers will also return True for isinstance(x, Coord).
I also have many functions and methods that accept these Coord types as arguments. I've set up decorators to check the arguments of these methods. Here is a simplified version:
class accepts(object):
def __init__(self, *types):
self.types = types
def __call__(self, func):
def wrapper(*args):
for i in len(args):
if not isinstance(args[i], self.types[i]):
raise TypeError
return func(*args)
return wrapper
This version is very simple, it still has some bugs. It's just there to illustrate the point. And it would be used like:
@accepts(numbers.Number, numbers.Number)
def add(x, y):
return x + y
Note: I'm only checking argument types against Abstract Base Classes.
Is this a good idea? Is there a better way to do it without having to repeat similar code in every method?
Edit:
What if I were to do the same thing, but instead of checking the types beforehand in the decorator, I catch the exceptions in the decorator:
class accepts(object):
def __init__(self, *types):
self.types = types
def __call__(self, func):
def wrapper(*args):
try:
return func(*args)
except TypeError:
raise TypeError, message
except AttributeError:
raise AttributeError, message
return wrapper
Is that any better?
for i in len(args): if not isinstance(args[i], self.types[i]):
tofor arg, type in zip(args, self.types): if not isinstance(arg, type):
– Culpepper