title: How can I make class properties immutable?
body: <p><code>@property</code> is a nice way to define getters. When the property is mutable, the reference returned can be used to modify the property in ways not controlled by the class definition. I'll use a banana stand as a motivating analogy, but this issue applies to any class that wraps a container.</p>
  
  <pre><code>class BananaStand:
      def __init__(self):
          self._money = 0
          self._bananas = ['b1', 'b2']
  
      @property
      def bananas(self):
          return self._bananas
  
      def buy_bananas(self, money):
          change = money
          basket = []
          while change &gt;= 1 and self._bananas:
              change -= 1
              basket.append(self._bananas.pop())
              self._money += 1
          return change, basket
  </code></pre>
  
  <p>I would like visitors to the banana stand to pay for their bananas. Unfortunately, there's nothing stopping a monkey (who doesn't know any better) from taking one of my bananas. The monkey didn't have to use the internal attribute <code>_banana</code>, they just took a banana without paying.</p>
  
  <pre><code>def take_banana(banana_stand):
      return banana_stand.bananas.pop()
  
  &gt;&gt;&gt; stand = BananaStand()
  &gt;&gt;&gt; stand.bananas
  ['b1', 'b2']
  &gt;&gt;&gt; take_banana(stand)
  'b2'
  &gt;&gt;&gt; stand.bananas
  ['b1']
  </code></pre>
  
  <p>This analogy is a little silly, but any class that has mutable attributes is not protected from accidental vandalism. In my actual case, I have a class with two array attributes that must remain the same length. With array, there's nothing stopping a user from splicing a second array into the first and silently breaking my equal size invariant:</p>
  
  <pre><code>&gt;&gt;&gt; from array import array
  &gt;&gt;&gt; x = array('f', [1,2,3])
  &gt;&gt;&gt; x
  array('f', [1.0, 2.0, 3.0])
  &gt;&gt;&gt; x[1:2] = array('f', [4,5,6])
  &gt;&gt;&gt; x
  array('f', [1.0, 4.0, 5.0, 6.0, 3.0])
  </code></pre>
  
  <p>This same behavour occurs when the array is a property.</p>
  
  <p>I can think of two ways of avoiding issue:</p>
  
  <ol>
  <li>Subclass array and override <code>__setitem__</code>. I am resistant to this because I would like to be able to use this array splicing behaviour internally.</li>
  <li>Change the accessor to return a deepcopy of the array. The returned array is still mutable, but changes to it won't affect the parent object.</li>
  </ol>
  
  <p>Is there an elegant way around this problem? I'm particularly interested in fancy ways of subclassing property.</p>