title: Using mutable sequence types as default attribute values together with @property in Python
body: <p>I get stuck on the following. I am trying to initialize some class attributes with default values, where the default values are mutable sequence types (list and numpy array). Because I want to have some error checking every time an attribute is set from outside the class I'm using the @property feature.</p>
  
  <pre><code>import numpy as np
  from FDTimeBase import FDTimeBase
  from FDString import FDString
  
  class FDObjNetwork(FDTimeBase):
  
      def __init__(self,i_mechObjs=[FDString(),FDString(101)],i_connPointMatrix=np.array([[0.5],[0.5]]),\
                   i_excPointMatrix=np.array([[0.5],[0.]])):
          self._mechObjs = i_mechObjs
          self._connPointMatrix = i_connPointMatrix
          self._excPointMatrix = i_excPointMatrix
  
      @property
      def mechObjs(self):
          """the mechanically vibrating objects making up the network"""
          return self._mechObjs
  
      @property
      def connPointMatrix(self):
          """
          the connection point matrix of the network, where each row
          denotes a separate element in the network and each column
          denotes a separate connection
          """
          return self._connPointMatrix
  
      @property
      def excPointMatrix(self):
          """
          the excitation point matrix, where each row denotes a
          separate element in the network and each column denotes a
          separate excitation distribution
          """
          return self._excPointMatrix
  
      @mechObjs.setter
      def mechObjs(self,newMechObjs):
          try:
              [obj.k for obj in newMechObjs]
          except AttributeError:
              raise AttributeError('argument mechObjs contains an invalid object')
          else:
              self._mechObjs = newMechObjs.tolist()[:]
  
      @connPointMatrix.setter
      def connPointMatrix(self,newConnPointMatrix):
          try:
              newConnPointMatrix[:,0]
          except TypeError:
              raise TypeError('argument connPointMatrix must be a 2D indexable object')
          else:
               self._connPointMatrix = np.asarray(newConnPointMatrix).copy()
  
      @excPointMatrix.setter
      def excPointMatrix(self,newExcPointMatrix):
          try:
              newExcPointMatrix[:,0]
          except TypeError:
              raise TypeError('argument excPointMatrix must be a 2D indexable object')
          else:
              self._excPointMatrix = np.asarray(newExcPointMatrix).cop()
  
      # public methods
      def calcModes(self):
          self.__checkDimensions()
  
      # private methods
      def __checkDimensions(self):
          if len(self.connPointMatrix[0,:]) != len(self.excPointMatrix[0,:]):
              raise Exception('arguments connPointMatrix and excPointMatrix must contain an equal nr. of rows')
          if len(self.connPointMatrix[0,:]) != len(self.mechObjs):
              raise Exception('the nr. of rows of argument connPointMatrix must be equal to the nr. of\
                              elements in mechObjs')
          if len(self.excPointMatrix[0,:]) != len(self.mechObjs):
              raise Exception('the nr. of rows of argument excPointMatrix must be equal to the nr. of\
                              elements in mechObjs')
  </code></pre>
  
  <p>Now when I create a new instance and try to access the mechObjs attribute I get an AttributeError and I don't understand why (same for the other two attributes). calling dir() on the instance I can see there are _mechObjs, _connPointMatrix and _excPointMatrix attributes which contain the list and array objects. Can somebody tell me what I'm doing wrong here? The object FDString is another custom class, which I omitted posting, since the source file is rather large. FDTimeBase is an object just holding 2 constant class attributes (nothing fancy).</p>
  
  <p>Thanks in advance</p>