An Overrideable Alternative to the property Function in Python

Revision History
Revision 0.12005-11-02

Initial draft.

Table of Contents


This article describes an alternative to Python's built-in property function which allows the user to override, in derived classes, the methods used by this function. The property function is one of Python's built in functions; it returns an object which implements Python's descriptor protocol in a well-defined way. Raymond Hettinger provides a clear exposition of descriptors in his article How-To Guide for Descriptors [Het04], which includes a brief discussion of the property function in the section Properties . Hettinger provides a pure-Python implementation of the property function; an equivalent version can also be found in the comments of the built-in implementation (for Python 2.4.2). This implementation illuminates exactly how this function works. As Hettinger describes and the implementation verifies, the property function binds functions to a class attribute that will be called when that attribute is retrieved, assigned, or deleted; such attributes we will call properties.

What happens in a class which derives from one with such a property, particularly one which overrides one or more of the methods used by its properties? The properties will clearly be defined in the derived class; Example 1, “A property in a derived class” shows—and the implementation confirms—that such properties will always refer to the original method from the base class. In this example, although we have overridden setval in the TwoPositiveAttempt derived class, when we assign the val property, the setval from the BePositive base class is called. This may be what you want, but I want to be able to define properties in base classes, and then to be able to simply override the methods assigned to these properties in derived classes. To continue this example, I wanted the second print statement to output Second: 16.

If you often find yourself using the property function to associate methods with class attributes, and you wish those methods would be inherited (and overrideable) in subclasses, then this exposition and implementation may be for you. Read on!

We can easily provide an alternative to the built-in version of Python's property function by basing our alternative on the Python version of that built-in version. I call my version OProperty [1]; the implementation can be found in Figure 1, “ OProperty class definition”.

Here, the OProperty class adds to the functionality of property in a straightforward way. It checks to see if the method that we've stored in this object has a name and is not a lambda function. If the method is a lambda function or does not have a name, then we fall back to the default behavior and just call the bound method directly. Otherwise, we get the current method with the name of the bound function on the current object and call that method. To see this in action, see Example 2, “Overriding property methods with OProperty.

[Het04] Raymond Hettinger. How-To Guide for Descriptors . Python Software Foundation. 2004.

[1] "O" for "Overrideable", "Object-oriented", "Other", or perhaps just for an exclamation of excitement. Take your pick, or come up with your own name.