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