When I try code like this:
def type_check(types):
def decorator(f):
def wrapper(self, v):
if not type(v) in types:
raise TypeError('Value is of type {} but allowed type(s): {}.'.format(type(v), types))
return f(self, v)
return wrapper
return decorator
class MyList:
@type_check(types=[list, MyList])
def __init__(self, value):
self.data = value[:]
# ... next are operator overloading and other unrelated to question code ...
I getting following traceback output:
MyList @type_check(types=[list, MyList]) NameError: name 'MyList' is not defined
I bypassed this by subclassing MyList from MyListAnchor and checking types with isinstance() instead of strict type equality:
def type_check(types):
def decorator(f):
def wrapper(self, v):
if not any(filter(lambda t: isinstance(v, t), types)):
raise TypeError('Value is of type {} but must be an instance(s) of: {}.'.format(type(v), types))
return f(self, v)
return wrapper
return decorator
class MyListAnchor:
pass
class MyList(MyListAnchor):
@type_check(types=[list, MyListAnchor])
def __init__(self, value):
self.data = value[:]
# ... next are operator overloading and other unrelated to question code ...
Is this the best solution? How to add function decorator to class method that accepts this class as one of decorator call arguments?
CodePudding user response:
You can decorate __init__
after the class is defined:
class MyList:
def __init__(self, value):
self.data = value[:]
MyList.__init__ = type_check(types=[list, MyList])(MyList.__init__)