Package: rwproperty
Author:Philipp von WeitershausenEmail:philikon@philikon.deLicense:Zope Public License, v2.1MotivationUsing method decorators and descriptors likeproperty, we can
easily create computed attributes:>>> class JamesBrown(object):
...     @property
...     def feel(self):
...         return self._feelAn attribute like this cannot be written, though.  You would have to
do something like this:>>> 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:>>> 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 thatapplyisgoing to go awayin Python 3000.GoalThere should be a way to declare a read & write property and still use
the compact and easy decorator spelling.  The read & 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 & write propertyRead & write properties work like regular properties.  You simply
define a method and then apply a decorator, except that you now don’t
use@propertybut@getpropertyto mark the getter and@setpropertyto mark the setter:>>> from rwproperty import getproperty, setproperty
>>> class JamesBrown(object):
...     @getproperty
...     def feel(self):
...         return self._feel
...     @setproperty
...     def feel(self, feel):
...         self._feel = feel>>> i = JamesBrown()
>>> i.feel
Traceback (most recent call last):
...
AttributeError: 'JamesBrown' object has no attribute '_feel'>>> i.feel = "good"
>>> i.feel
'good'The order in which getters and setters are declared doesn’t matter:>>> from rwproperty import getproperty, setproperty
>>> class JamesBrown(object):
...     @setproperty
...     def feel(self, feel):
...         self._feel = feel
...     @getproperty
...     def feel(self):
...         return self._feel>>> i = JamesBrown()
>>> i.feel = "good"
>>> i.feel
'good'Of course, deleters are also possible:>>> from rwproperty import delproperty
>>> 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>>> i = JamesBrown()
>>> i.feel = "good"
>>> del i.feel
>>> i.feel
Traceback (most recent call last):
...
AttributeError: 'JamesBrown' object has no attribute '_feel'Edge casesThere might be a case where you’re using a flavour of read & write
properties and already have a non-property attribute of the same name
defined:>>> class JamesBrown(object):
...     feel = "good"
...     @getproperty
...     def feel(self):
...         return "so good"
...
Traceback (most recent call last):
...
TypeError: read & write properties cannot be mixed with other attributes except regular property objects.