Home > Mobile >  How to add function decorator to class method that accepts this class as one of decorator call argum
How to add function decorator to class method that accepts this class as one of decorator call argum

Time:07-12

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__)
  • Related