Add Properties to Instances?
Bengt Richter
bokr at oz.net
Sat Mar 12 23:46:25 EST 2005
On Sun, 13 Mar 2005 03:18:51 GMT, bokr at oz.net (Bengt Richter) wrote:
>On 12 Mar 2005 09:48:42 -0800, "Martin Miller" <ggrp1.20.martineau at dfgh.net> 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
More information about the Python-list
mailing list