Properties on old-style classes actually work?

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Mon May 7 05:12:35 EDT 2007


On Mon, 07 May 2007 10:44:35 +0200, Paul Melis wrote:

> Hello,
> 
> The python library docs read in section 2.1
> (http://docs.python.org/lib/built-in-funcs.html):
> 
> "
> ...
> 
> property(  	[fget[, fset[, fdel[, doc]]]])
>      Return a property attribute for new-style classes (classes that
> derive from object).
> 
> ...
> "
> 
> 
> But in 2.4 at least properties also seem to work for old-style classes:


Unfortunately, they don't -- they seem to work until you try assigning to 
them. Here's the same property implemented with a new-style and old-style 
class:


class New(object):
    def __init__(self, s):
        self._value = s
    def upgetter(self):
        return self._value.upper()
    def upsetter(self, s):
        self._value = s
    value = property(upgetter, upsetter)

class Old:
    def __init__(self, s):
        self._value = s
    def upgetter(self):
        return self._value.upper()
    def upsetter(self, s):
        self._value = s
    value = property(upgetter, upsetter)


Properties work with new-style classes:

>>> obj = New('norwegian blue')
>>> obj.value
'NORWEGIAN BLUE'
>>> obj.value = 'nobody expects the spanish inquisition!'
>>> obj.value
'NOBODY EXPECTS THE SPANISH INQUISITION!'


At first, they seem to work with old-style classes:

>>> obj = Old('norwegian blue')
>>> obj.value
'NORWEGIAN BLUE'

But problems occur once you try assigning to it:

>>> obj.value = 'nobody expects the spanish inquisition!'
>>> obj.value
'nobody expects the spanish inquisition!'

And now it is easy to see why:

>>> obj.__dict__['value']
'nobody expects the spanish inquisition!'
>>> obj.__dict__['_value']
'norwegian blue'

The call to assign obj.value over-rides the property with the raw value, 
and from that moment on, obj.value is no longer a property, but just an 
ordinary instance attribute.


-- 
Steven.



More information about the Python-list mailing list