[Tutor] New-style classes

Kent Johnson kent37 at tds.net
Thu Sep 29 14:02:19 CEST 2005


Jan Eden wrote:
> Hi,
> 
> after updating a program to use new-style classes, I am a bit confused. My setup looks like this (simplified):
> 
> #Show.py
> 
> import Data
> 
> class Base(object):
>     ...
>     
> class Page(Data.Page, Base):
>     ...
> 
> class Author(Data.Author, Base):
> ...
> 
> #Data.py
> 
> class Base:
>     ...
> 
> class Page(Base):
>     ...
> 
> class Author(Base):
>     ...
> 
> The module Show.py provides methods, Data.py provides data
> attributes. I use the property method in Data.Base for a certain
> attribute - but why does this work?
> 
> Data.Base has no base classes, so it is not based on a built-in type:
> How can it be a new-style class?

Data.Base is not a new-style class, but the classes in Show are. And properties may appear to work in old-style classes. This document
http://www.python.org/2.2.3/descrintro.html#property
says,
Properties do not work for classic classes, but you don't get a clear error when you try this. Your get method will be called, so it appears to work, but upon attribute assignment, a classic class instance will simply set the value in its __dict__ without calling the property's set method, and after that, the property's get method won't be called either.

Here is an old-style class that defines a property:

 >>> class OldStyle:
 ...     def getA(self):
 ...         print "getA"
 ...         return self.__a
 ...     def setA(self, value):
 ...         print "setA"
 ...         self.__a = value
 ...     a = property(getA, setA)
 ...
 >>> o=OldStyle()

OldStyle.getA() is called the first time I access o.a:
 >>> o.a
getA
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 4, in getA
AttributeError: OldStyle instance has no attribute '_OldStyle__a'

Setting a value for a wipes out the property, now it behaves like a normal attribute:
 >>> o.a = 3
 >>> o.a
3

A class that inherits from object and OldStyle is a new-style class and the property works as expected:
 >>> class NewStyle(object, OldStyle):
 ...   pass
 ...
 >>> n=NewStyle()
 >>> n.a
getA
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 4, in getA
AttributeError: 'NewStyle' object has no attribute '_OldStyle__a'
 >>> n.a=3
setA
 >>> n.a
getA
3

Kent



More information about the Tutor mailing list