title: Decorators or assertions in setters to check property type?
body: <p>In a python project, my class has several properties that I need to be of specific type.  Users of the class must have the ability to set the property.</p>
  
  <p>What is the best way to do this?  Two solutions come to my mind:
  1. Have test routines in each setter function.
  2. Use decorators for attributes</p>
  
  <p>My current solution is 1 but I am not happy with it due to the code duplication.  It looks like this:</p>
  
  <pre><code>class MyClass(object):
      @property
      def x(self):
          return self._x
  
      @x.setter
      def x(self, val):
          if not isinstance(self, int):
              raise Exception("Value must be of type int")
          self._x = val
  
      @property
      def y(self):
          return self._y
  
      @x.setter
      def y(self, val):
          if not isinstance(self, (tuple, set, list)):
              raise Exception("Value must be of type tuple or set or list")
          self._y = val
  </code></pre>
  
  <p>From what I know of decorators, it should be possible to have a decorator before <code>def x(self)</code> handle this job.  Alas I fail miserably at this, as all examples I found (like <a href="https://stackoverflow.com/questions/12911395/using-decorators-in-python-for-type-checking">this</a> or <a href="https://stackoverflow.com/questions/36879932/python-type-checking-decorator">this</a>) are not targeted at what I want.</p>
  
  <p>The first question is thus: <em>Is it better to use a decorator to check property types?</em> If yes, the next question is: What is wrong with below decorator (I want to be able write <code>@accepts(int)</code>?</p>
  
  <pre><code>def accepts(types):
      """Decorator to check types of property."""
      def outer_wrapper(func):
          def check_accepts(prop):
              getter = prop.fget
              if not isinstance(self[0], types):
                  msg = "Wrong type."
                  raise ValueError(msg)
              return self
          return check_accepts
      return outer_wrapper
  </code></pre>