Metadata-Version: 2.0 Name: classproperty Version: 1.0 Summary: Class properties Home-page: http://www.z3lab.org/sections/blogs/philipp-weitershausen/2006_05_29_pycon-06-lightning-talk Author: Philipp von Weitershausen Author-email: philipp@weitershausen.de License: ZPL Download-URL: http://codespeak.net/svn/user/philikon/classproperty#egg=classproperty-dev Platform: UNKNOWN Class 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: >>> 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: >>> 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 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 & 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. Class properties ---------------- Class properties let you define properties via the ``class`` statement. You define a dynamic property as if you were implementing a class. This works like this: >>> from classproperty import classproperty >>> class JamesBrown(object): ... class feel(classproperty): ... def __get__(self): ... return self._feel ... def __set__(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' Of course, deleters are also possible: >>> class JamesBrown(object): ... class feel(classproperty): ... def __get__(self): ... return self._feel ... def __set__(self, feel): ... self._feel = feel ... def __delete__(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'