On Sun, 13 Mar 2005 03:18:51 GMT, [EMAIL PROTECTED] (Bengt Richter) wrote: >On 12 Mar 2005 09:48:42 -0800, "Martin Miller" <[EMAIL PROTECTED]> wrote: > >>I'm trying to create some read-only instance specific properties, but >>the following attempt didn't work: >> >>> class Foobar(object): >>> pass >>> >>> foobar = Foobar() >>> foobar.x = property(fget=lambda: 42) >>> >>> print "foobar.x:", foobar.x >> >>Which results in the following ouput instead of '42': >> foobar.x: <property object at 0x00AE57B0> >> >>I also tried this: >>> foobar.__dict__['x'] = property(fget=lambda: 42) >>but get the same behavior. >> >>Can anyone tell me what's wrong with this approach (and perhaps the >>correct way to do it, if there is one)? >> >One way is to doctor the instance attribute access to do what >happens with a property when it is implemented normally as an >attribute of the class. E.g., (using InstProp in place of your Foobar) > > >>> class InstProp(object): > ... def __getattribute__(self, attr): > ... p = object.__getattribute__(self, attr) > ... if isinstance(p, property): return p.__get__(self) > ... return p > ... Actually, checking for being a property instance is more restrictive than normal default processing. Checking for __get__ would be better.
This would let you use a function as an instance-specific method as well, since functions have __get__ methods, and that is how they become bound methods etc. We'll also pass the type of the instance, to give __get__ everything it needs for a proper bound method. >>> class InstProp(object): ... def __getattribute__(self, attr): ... p = object.__getattribute__(self, attr) ... if hasattr(p, '__get__'): return p.__get__(self, type(self)) ... return p ... >>> inst = InstProp() >>> def bar(self, *args): print 'bar method called with %r'% (args,) ... >>> inst.bar = bar >>> inst.bar <bound method InstProp.bar of <__main__.InstProp object at 0x02EF1E8C>> >>> inst.baz = lambda self: 'baz method' >>> >>> inst.baz <bound method InstProp.<lambda> of <__main__.InstProp object at 0x02EF1E8C>> >>> inst.baz() 'baz method' >>> inst.p = property(lambda self: 'property p') >>> inst.p 'property p' Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list