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 _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor