On 2004-12-28 12:05:20, Bob.Cowdery@CGI-Europe.com wrote: > class NOTOK(object): > > def __init__(self): > self.__x = 0 > self.x = property(self.getx, self.setx, self.delx, "I'm the 'x' > property.") > > def getx(self): return self.__x - 5 > def setx(self, value): self.__x = value + 10 > def delx(self): del self.__x > The OK example has the property and it clearly goes through the get/set > methods. The NOTOK example creates a property object for x. When I set x it > creates a new property x which clearly does not invoke the get/set methods. > Am I doing something stupid here? Properties must be set on a class level. The "magic" thing about properties is that property() generates an object with __get__, __set__ and __delete__ methods. Properties are then defined at the class definition level, as previously mentioned. The property() function wraps the methods into a property object, stored as OK.x. Now, the part where the magic is introduced when accessing attributes. Remember the normal lookup order for attributes, like obj.x: 1. First, check if this is a local attribute defined in obj.__dict__ (like when stored as self.x = something in __init__) 2. If that fails, go to the class(es) of obj, and look for the attribute there, it might be a class attribute. If this doesn't work, the parent classes are visited, etc. This applies to both attributes and methods. For methods, something else is done. When accessing obj.method - the method is wrapped so that the first parameter self is set automatically to the object obj. In new-style classes, this wrapping is performed by the so-called metaclass, normally the class "type". This is the same metaclass that takes care of getting attributes from the superclasses if it is not found. All this is is done in type.__getattribute__ (I think.. haven't got time to check this up). This method handles attribute lookup for all methods and attributes in normal classes, like your OK and NOOK. In this attribute lookup, if the metaclass finds an object that implements __get__, the result of calling that method will be returned instead of the object itself. This is what happens to properties stored in the class. If you set the property object in __init__, you are storing the property object in the objects own attribute namespace, in __dict__. Therefore, the metaclass will never be involved, as object.__getattribute__ doesn't handle properties, but just return the objects from __dict__ unchanged. If you want to support this, for some reason or another, you can implement the wrapping your self in NOTOK like this: class NOTOK(object): def __getattribute__(self, key): obj = object.__getattribute__(key) if hasattr(obj, "__get__"): return obj.__get__() return obj # And similar for __setattr__ and __delattr__ See http://users.rcn.com/python/download/Descriptor.htm for further details. -- Stian Søiland Work toward win-win situation. Win-lose Trondheim, Norway is where you win and the other lose. http://soiland.no/ Lose-lose and lose-win are left as an exercise to the reader. [Limoncelli/Hogan] Og dette er en ekstra linje -- http://mail.python.org/mailman/listinfo/python-list