detecting property modification

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Fri Dec 21 18:13:07 EST 2007


Mangabasi a écrit :
> On Dec 21, 4:46 pm, Bruno Desthuilliers
> <bdesth.quelquech... at free.quelquepart.fr> wrote:
> 
>>Mangabasi a écrit :
>>(snip)
>>
>>
>>
>>
>>>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?
>>
>>Wrong. That means that attribute lookup rules are invoked, which may *or
>>not* end up calling the Body *intance*'s __dict__ __setitem__ method to
>>be called. Anyway:
>>
>>
>>> 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?
>>
>>This still won't solve your problem. What you want to trace are method
>>calls on the objects returned by attribute lookup on instances of Body -
>>not calls to instances __dict__ methods. In your example, what you want
>>to trace are calls to pos.__getitem__, not calls to b.__dict__.__getitem__.
>>
>>And if you what you really want is to trace any mutator call to any
>>arbitrary object that may become an attribute of b, then I'm afraid
>>you're in for a hard time...
> 
> 
> Now I am curious about these "attribute lookup rules".
> My understanding was:
> 
> When an attribute name is accessed in an instance
> 
> First __getattribute__(self, name) is called.

Which is itself resolved first (methods being attributes) !-)

__getattribute__ can itself be overloaded, so the only thing you can bet 
is that the first __getattribute__ method found in the mro will be 
called. All the rest is the *default* lookup rule:

>  This guy looks into the
> instance's dictionary for the name,

Yes.

> if not found then looks into the
> parent class's dictionary,

You mean : the class's dictionnary.

> if not found searches the base classes, if
> not found checks __getattr__,

and invoke it if found

> still not found raises an
> AttributeError.

> Does this look right?

Given the above corrections, mostly, yes. Note that the first one 
already makes a big difference. Also, it doesn't take into accounts 
__slots__ and descriptors. Let's ignore slots for the moment - we still 
have descriptors (property, functions, and other computed attributes), 
which have their __get__ method invoked when looked up.



>  If not, are these attribute lookup rules
> documented somewhere?  I have not been paying much attention to the
> new style classes, have things changed with the introduction of these
> new style classes?

Well, yes, somewhat. Else we wouldn't have them, isn't it ?

Anyway, wrt/ your problem, wether you use old-style or new-style classes 
won't make much difference: hooking into Body's instances attribute 
lookup won't let you trace attribute lookup on objects that are 
themselves attributes of a Body instance (hmmm, not very clear, 
sorry...re-reading it slowly, it should make sens. Hopefully...).



More information about the Python-list mailing list