[Tutor] Counting method calls

Ricardo Aráoz ricaraoz at gmail.com
Mon Sep 24 03:13:51 CEST 2007


Kent Johnson wrote:
> Ricardo Aráoz wrote:
>> Kent Johnson wrote:
>>> One more reference:
>>> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252151
>>>
>>> This appears as recipe 6.6 in the second edition of the printed
>>> cookbook.
>>>
>>> Kent
>>
>> Thanks Kent. I guess I got into deep waters.
>> It's a shame though that you can not do this in a simple manner,
>> considering python simplifies so many other chores.
> 
> I agree, also because it is so easy to do with old-style classes.
> 
> The root of the problem seems to be that new-style classes do not use
> the normal attribute lookup mechanism to find special methods when they
> are being invoked by the interpreter *as* special methods. For example,
> when executing a[0], __getattribute__() is not called on the class of a
> or its metaclass. Instead the predefined slot for __getitem__ is
> accessed; if it is empty then indexing is not allowed.
> 
> Here is a demonstration that __getattribute__() is not called on the
> class or the metaclass when __getitem__() is accessed as a special method:
> 
> In [4]: class ShowMeta(type):
>    ...:     def __getattribute__(self, name):
>    ...:         print 'ShowMeta:', name
>    ...:         return type.__getattribute__(self, name)
>    ...:
>    ...:
> In [5]: class Show(object):
>    ...:     def __getattribute__(self, name):
>    ...:         print 'Show:', name
>    ...:         return object.__getattribute__(self, name)
>    ...:     __metaclass__ = ShowMeta
>    ...:
>    ...:
> In [6]: a=Show()
> In [7]: a[1]
> ------------------------------------------------------------
> Traceback (most recent call last):
>   File "<ipython console>", line 1, in <module>
> <type 'exceptions.TypeError'>: 'Show' object is unindexable
> 
> Notice that neither __getattribute__() is called. OTOH if __getitem__()
> is accessed as a normal attribute then Show.__getattribute__() *is* called:
> 
> In [9]: a.__getitem__(0)
> Show: __getitem__
> ------------------------------------------------------------
> Traceback (most recent call last):
>   File "<ipython console>", line 1, in <module>
>   File "<ipython console>", line 4, in __getattribute__
> <type 'exceptions.AttributeError'>: 'Show' object has no attribute
> '__getitem__'
> 
> The only way to put something in the __getitem__ slot to assign to
> cls.__getitem__. That is why the cookbook recipe copies methods from the
> delegate into the proxy. It seems unfortunate that the recipe requires
> knowing which special methods you want to delegate. Maybe an approach
> like the one here
> http://groups.google.com/group/comp.lang.python/msg/f4bf020fd94d631a
> of delegating all special methods with a list of exceptions would work
> better.
> 
> Kent
> 

Anyway, if you have to know the innards of the language to be able to do
it then it is not good. If nothing else it is against encapsulation. An
application writer should not need to know those things in order to
accomplish a simple concept as intercepting all methods. I think I'll
stay with old style classes for this, the code is simpler and easy to
understand what you are doing.








More information about the Tutor mailing list