|
|
Subject: detecting property modification
From: Jean-Paul Calderone
Date: 12/21/2007 1:11:55 PM
On Fri, 21 Dec 2007 09:49:51 -0800 (PST), Mangabasi <mangabasi@gmail.com> wrote:
> [snip]
>
>Hi Jean-Paul,
>
>Sorry, I should have spelled this out in my post but I did not. For
>several reasons I do not wish to couple the pos object with the Body
>instances. In my case, I did not want pos objects (in my example they
>were lists but they can be other objects as well) to care about their
>parents. So the question is: How do we detect this in the Body?
>
You can't. If you have this:
b = Body([1, 2])
b.pos[0] = 3
Then Body gets asked for the value of the attribute; then, that
object (a list in the case of this example) gets told to change
its 0th element to 3. There is no way for Body to get in the
way of the second message, except by doing what I said - adding
a wrapper around the list so that it _can_ get in the way.
This doesn't require the list to know anything about Body, though.
_Body_ should apply the wrapper.
For example, new-style:
class Body(object):
def get_pos(self):
return ChangeNoticingListWrapper(self._pos)
def set_pos(self, value):
self._pos = value
pos = property(get_pos, set_pos)
def __init__(self, pos):
self.pos = pos
class ChangeNoticingListWrapper(object):
def __init__(self, wrapped):
self.wrapped = wrapped
def __setitem__(self, index, value):
print 'Changing', index, 'to', value
self.wrapped[index] = value
b = Body([1, 2])
b.pos[0] = 3
Jean-Paul
Subject: detecting property modification
From: Jean-Paul Calderone
Date: 12/21/2007 1:43:38 PM
On Fri, 21 Dec 2007 10:30:31 -0800 (PST), Mangabasi <mangabasi@gmail.com> wrote:
>On Dec 21, 1:11 pm, Jean-Paul Calderone <exar...@divmod.com> wrote:
>> On Fri, 21 Dec 2007 09:49:51 -0800 (PST), Mangabasi <mangab...@gmail.com> wrote:
>> > [snip]
>>
>> >Hi Jean-Paul,
>>
>> >Sorry, I should have spelled this out in my post but I did not. For
>> >several reasons I do not wish to couple the pos object with the Body
>> >instances. In my case, I did not want pos objects (in my example they
>> >were lists but they can be other objects as well) to care about their
>> >parents. So the question is: How do we detect this in the Body?
>>
>> You can't. If you have this:
>>
>> b = Body([1, 2])
>> b.pos[0] = 3
>>
>> Then Body gets asked for the value of the attribute; then, that
>> object (a list in the case of this example) gets told to change
>> its 0th element to 3. There is no way for Body to get in the
>> way of the second message, except by doing what I said - adding
>> a wrapper around the list so that it _can_ get in the way.
>>
>> This doesn't require the list to know anything about Body, though.
>> _Body_ should apply the wrapper.
>>
>> For example, new-style:
>>
>> class Body(object):
>> def get_pos(self):
>> return ChangeNoticingListWrapper(self._pos)
>> def set_pos(self, value):
>> self._pos = value
>> pos = property(get_pos, set_pos)
>> def __init__(self, pos):
>> self.pos = pos
>>
>> class ChangeNoticingListWrapper(object):
>> def __init__(self, wrapped):
>> self.wrapped = wrapped
>> def __setitem__(self, index, value):
>> print 'Changing', index, 'to', value
>> self.wrapped[index] = value
>>
>> b = Body([1, 2])
>> b.pos[0] = 3
>>
>> Jean-Paul
>
>
>Hi Jean-Paul,
>
>I see what you are saying but my contrived example is not doing a good
>job explaining the real issue I am having here.
>
>When you say "The Body gets asked for the value of the attribute" that
>means that Body's __dict__ is being asked to provide a value
>corresponding to its 'pos' key, right? Now I may want to ask a more
>specific question here. How do I modify Body's __dict__ so that I can
>perform a task when __getitem__ method of the __dict__ is called?
You can't do that. Fortunately, there's no reason to. Changing the
behavior of __getitem__ on the __dict__ of a Body instance would let
you address the exact same use-case as a property or a __getattr__
implementation lets you address. Maybe you are asking whether there
is a special method called __getitem__ which is invoked when attributes
are looked up? If so, yes, there is. You can also use a property, as
in the example I gave.
None of that has anything to do with looking up values in the result of
the attribute lookup, though. For example, it doesn't help you change
the behavior of "pos[0]".
Jean-Paul
|