Next / Previous / Contents / TCC Help System / NM Tech homepage

21.15. property(): Create an access-controlled attribute

The purpose of this function is to create a property of a class. A property looks and acts like an ordinary attribute, except that you provide methods that control access to the attribute.

There are three kinds of attribute access: read, write, and delete. When you create a property, you can provide any or all of three methods that handle requests to read, write, or delete that attribute.

Here is the general method for adding a property named p to a new-style class C.

class C(...):
    def R(self):
        ...read method...
    def W(self, value):
        ...write method...
    def D(self):
        ...delete method...
    p = property(R, W, D, doc)
    ...

where:

As an example, here is a small class that defines a property named x:

class C(object):
    def __init__(self):
        self.__x=None
    def getx(self):
        print "+++ getx()"
        return self.__x
    def setx(self, v):
        print "+++ setx({0})".format(v)
        self.__x  =  v
    def delx(self):
        print "+++ delx()"
        del self.__x
    x=property(getx, setx, delx, "Me property 'x'.")

Assuming that class is defined, here is a conversational example.

>>> c=C()
>>> print c.x
+++ getx()
None
>>> print C.x.__doc__
Me property 'x'.
>>> c.x=15
+++ setx(15)
>>> c.x
+++ getx()
15
>>> del c.x
+++ delx()
>>> c.x
+++ getx()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in getx
AttributeError: 'C' object has no attribute '_C__x'

Starting with Python 2.6, this function can also be used as a decorator (see Section 24.4, “Decorators”). The decorated method is used as the getter method. Furthermore, the decorated method will itself have two decorators named setter and deleter; you can use these decorators to define setter and deleter methods.

For example, suppose you want to provide your class with a property named state, and youra getter method returns a private attribute named ._state. You could define it like this:

    @property
    def state(self):
        '''The internal state property.'''
        return self._state

In this example, not only will the .state() method be the getter for this property, but the documentation string '''The internal state property.''' will be stored as the documentation string for the property.

Suppose further that you want to write a setter method that checks to make sure the argument is a positive number less than or equal to 2. To use the built-in setter method to write your setter, give the function the same name as the property, and decorate it with P.setter where P is the name of the previously defined getter:

    @state.setter
    def state(self, k):
        if not (0 <= k <= 2):
            raise ValueError("Must be 0 through 2 inclusive!")
        else:
            self._state = k

Similarly, you can write a deleter method by decorating it with P.deleter:

    @state.deleter
    def state(self):
        del self._state