[Tutor] Counting method calls
Kent Johnson
kent37 at tds.net
Mon Sep 24 02:15:34 CEST 2007
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
More information about the Tutor
mailing list