title: How should I expose read-only fields from Python classes?
body: <p>I have many different small classes which have a few fields each, e.g. this:</p>
  
  <pre><code>class Article:
      def __init__(self, name, available):
          self.name = name
          self.available = available
  </code></pre>
  
  <p>What's the easiest and/or most idiomatic way to make the <code>name</code> field read only, so that</p>
  
  <pre><code>a = Article("Pineapple", True)
  a.name = "Banana"  # &lt;-- should not be possible
  </code></pre>
  
  <p>is not possible anymore?</p>
  
  <p>Here's what I considered so far:</p>
  
  <ol>
  <li><p>Use a getter (ugh!).</p>
  
  <pre><code>class Article:
      def __init__(self, name, available):
          self._name = name
          self.available = available
  
      def name(self):
          return self._name
  </code></pre>
  
  <p>Ugly, non-pythonic - and a lot of boilerplate code to write (especially if I have multiple fields to make read-only). However, it does the job and it's easy to see why that is.</p></li>
  <li><p>Use <a href="http://docs.python.org/release/2.5.2/ref/attribute-access.html" rel="noreferrer"><code>__setattr__</code></a>:</p>
  
  <pre><code>class Article:
      def __init__(self, name, available):
          self.name = name
          self.available = available
  
      def __setattr__(self, name, value):
          if name == "name":
              raise Exception("%s property is read-only" % name)
          self.__dict__[name] = value
  </code></pre>
  
  <p>Looks pretty on the caller side, seems to be the idiomatic way to do the job - but unfortunately I have many classes with only a few fields to make read only each. So I'd need to add a <code>__setattr__</code> implementation to all of them. Or use some sort of mixin maybe? In any case, I'd need to make up my mind how to behave in case a client attempts to assign a value to a read-only field. Yield some exception, I guess - but which?</p></li>
  <li><p>Use a utility function to define properties (and optionally getters) automatically. This is basically the same idea as (1) except that I don't write the getters explicitely but rather do something like</p>
  
  <pre><code>class Article:
      def __init__(self, name, available):
          # This function would somehow give a '_name' field to self
          # and a 'name()' getter to the 'Article' class object (if
          # necessary); the getter simply returns self._name
          defineField(self, "name")
          self.available = available
  </code></pre>
  
  <p>The downside of this is that I don't even know if this is possible (or how to implement it) since I'm not familiar with runtime code generation in Python. :-)</p></li>
  </ol>
  
  <p>So far, (2) appears to be most promising to me except for the fact that I'll need <code>__setattr__</code> definitions to all my classes. I wish there was a way to 'annotate' fields so that this happens automatically. Does anybody have a better idea?</p>
  
  <p>For what it's worth, I'mu sing Python 2.6.</p>
  
  <p><b>UPDATE:</b>
  Thanks for all the interesting responses! By now, I have this:</p>
  
  <pre><code>def ro_property(o, name, value):
      setattr(o.__class__, name, property(lambda o: o.__dict__["_" + name]))
      setattr(o, "_" + name, value)
  
  class Article(object):
      def __init__(self, name, available):
          ro_property(self, "name", name)
          self.available = available
  </code></pre>
  
  <p>This seems to work quite nicely. The only changes needed to the original class are</p>
  
  <ul>
  <li>I need to inherit <code>object</code> (which is not such a stupid thing anyway, I guess)</li>
  <li>I need to change <code>self._name = name</code> to <code>ro_property(self, "name", name)</code>.</li>
  </ul>
  
  <p>This looks quite neat to me - can anybody see a downside with it?</p>