<?xml version="1.0" encoding="UTF-8" ?>
<rdf:RDF xmlns="http://usefulinc.com/ns/doap#" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><Project><name>rwproperty</name>
<shortdesc>Read &amp; write properties</shortdesc>
<description>Read &amp; write properties
========================

:Author:   Philipp von Weitershausen
:Email:    philikon@philikon.de
:License:  Zope Public License, v2.1

Motivation
----------

Using method decorators and descriptors like ``property``, we can
easily create computed attributes:

  &gt;&gt;&gt; class JamesBrown(object):
  ...     @property
  ...     def feel(self):
  ...         return self._feel

An attribute like this cannot be written, though.  You would have to
do something like this:

  &gt;&gt;&gt; class JamesBrown(object):
  ...     def _getFeel(self):
  ...         return self._feel
  ...     def _setFeel(self, feel):
  ...         self._feel = feel
  ...     feel = property(_getFeel, _setFeel)

The problem with this approach is that it leaves the getter and setter
sitting around in the class namespace.  It also lacks the compact
spelling of a decorator solution.  To cope with that, some people like
to write:

  &gt;&gt;&gt; class JamesBrown(object):
  ...     @apply
  ...     def feel():
  ...         def get(self):
  ...             return self._feel
  ...         def set(self, feel):
  ...             self._feel = feel
  ...         return property(get, set)

This spelling feels rather cumbersome, apart from the fact that
``apply`` is `going to go away`_ in Python 3000.

.. _going to go away: http://www.python.org/peps/pep-3000.html#id24


Goal
----

There should be a way to declare a read &amp; write property and still use
the compact and easy decorator spelling.  The read &amp; write properties
should be as easy to use as the read-only property.  We explicitly
don't want that immediately called function that really just helps us
name the attribute and create a local scope for the getter and setter.


Read &amp; write property
---------------------

Read &amp; write properties work like regular properties.  You simply
define a method and then apply a decorator, except that you now don't
use ``@property`` but ``@getproperty`` to mark the getter and
``@setproperty`` to mark the setter:

  &gt;&gt;&gt; from rwproperty import getproperty, setproperty
  &gt;&gt;&gt; class JamesBrown(object):
  ...     @getproperty
  ...     def feel(self):
  ...         return self._feel
  ...     @setproperty
  ...     def feel(self, feel):
  ...         self._feel = feel

  &gt;&gt;&gt; i = JamesBrown()
  &gt;&gt;&gt; i.feel
  Traceback (most recent call last):
  ...
  AttributeError: 'JamesBrown' object has no attribute '_feel'

  &gt;&gt;&gt; i.feel = "good"
  &gt;&gt;&gt; i.feel
  'good'

The order in which getters and setters are declared doesn't matter:

  &gt;&gt;&gt; from rwproperty import getproperty, setproperty
  &gt;&gt;&gt; class JamesBrown(object):
  ...     @setproperty
  ...     def feel(self, feel):
  ...         self._feel = feel
  ...     @getproperty
  ...     def feel(self):
  ...         return self._feel

  &gt;&gt;&gt; i = JamesBrown()
  &gt;&gt;&gt; i.feel = "good"
  &gt;&gt;&gt; i.feel
  'good'

Of course, deleters are also possible:

  &gt;&gt;&gt; from rwproperty import delproperty
  &gt;&gt;&gt; class JamesBrown(object):
  ...     @setproperty
  ...     def feel(self, feel):
  ...         self._feel = feel
  ...     @getproperty
  ...     def feel(self):
  ...         return self._feel
  ...     @delproperty
  ...     def feel(self):
  ...         del self._feel

  &gt;&gt;&gt; i = JamesBrown()
  &gt;&gt;&gt; i.feel = "good"
  &gt;&gt;&gt; del i.feel
  &gt;&gt;&gt; i.feel
  Traceback (most recent call last):
  ...
  AttributeError: 'JamesBrown' object has no attribute '_feel'


Edge cases
----------

There might be a case where you're using a flavour of read &amp; write
properties and already have a non-property attribute of the same name
defined:

  &gt;&gt;&gt; class JamesBrown(object):
  ...     feel = "good"
  ...     @getproperty
  ...     def feel(self):
  ...         return "so good"
  ...
  Traceback (most recent call last):
  ...
  TypeError: read &amp; write properties cannot be mixed with other attributes except regular property objects.</description>
<homepage rdf:resource="http://pypi.python.org/pypi/rwproperty" />
<maintainer><foaf:Person><foaf:name>Philipp von Weitershausen</foaf:name>
<foaf:mbox_sha1sum>6fd6ed799b2a4172c08432f022eb5a83114c99ca</foaf:mbox_sha1sum></foaf:Person></maintainer>
<release><Version><revision>1.0</revision></Version></release>
</Project></rdf:RDF>