DESCRIPTION.rst 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. Class properties
  2. ================
  3. :Author: Philipp von Weitershausen
  4. :Email: philikon@philikon.de
  5. :License: Zope Public License, v2.1
  6. Motivation
  7. ----------
  8. Using method decorators and descriptors like ``property``, we can
  9. easily create computed attributes:
  10. >>> class JamesBrown(object):
  11. ... @property
  12. ... def feel(self):
  13. ... return self._feel
  14. An attribute like this cannot be written, though. You would have to
  15. do something like this:
  16. >>> class JamesBrown(object):
  17. ... def _getFeel(self):
  18. ... return self._feel
  19. ... def _setFeel(self, feel):
  20. ... self._feel = feel
  21. ... feel = property(_getFeel, _setFeel)
  22. The problem with this approach is that it leaves the getter and setter
  23. sitting around in the class namespace. It also lacks the compact
  24. spelling of a decorator solution. To cope with that, some people like
  25. to write:
  26. >>> class JamesBrown(object):
  27. ... @apply
  28. ... def feel():
  29. ... def get(self):
  30. ... return self._feel
  31. ... def set(self, feel):
  32. ... self._feel = feel
  33. ... return property(get, set)
  34. This spelling feels rather cumbersome, apart from the fact that
  35. ``apply`` is `going to go away`_ in Python 3000.
  36. .. _going to go away: http://www.python.org/peps/pep-3000.html#id24
  37. Goal
  38. ----
  39. There should be a way to declare a read & write property and still use
  40. the compact and easy decorator spelling. The read & write properties
  41. should be as easy to use as the read-only property. We explicitly
  42. don't want that immediately called function that really just helps us
  43. name the attribute and create a local scope for the getter and setter.
  44. Class properties
  45. ----------------
  46. Class properties let you define properties via the ``class``
  47. statement. You define a dynamic property as if you were implementing
  48. a class. This works like this:
  49. >>> from classproperty import classproperty
  50. >>> class JamesBrown(object):
  51. ... class feel(classproperty):
  52. ... def __get__(self):
  53. ... return self._feel
  54. ... def __set__(self, feel):
  55. ... self._feel = feel
  56. >>> i = JamesBrown()
  57. >>> i.feel
  58. Traceback (most recent call last):
  59. ...
  60. AttributeError: 'JamesBrown' object has no attribute '_feel'
  61. >>> i.feel = "good"
  62. >>> i.feel
  63. 'good'
  64. Of course, deleters are also possible:
  65. >>> class JamesBrown(object):
  66. ... class feel(classproperty):
  67. ... def __get__(self):
  68. ... return self._feel
  69. ... def __set__(self, feel):
  70. ... self._feel = feel
  71. ... def __delete__(self):
  72. ... del self._feel
  73. >>> i = JamesBrown()
  74. >>> i.feel = "good"
  75. >>> del i.feel
  76. >>> i.feel
  77. Traceback (most recent call last):
  78. ...
  79. AttributeError: 'JamesBrown' object has no attribute '_feel'