On 14 Mar 2005 17:43:53 -0800, [EMAIL PROTECTED] wrote: > >Why doesn't this work? > >>>> def foo(lst): >... class baz(object): >... def __getitem__(cls, idx): return cls.lst[idx] >... __getitem__=classmethod(__getitem__) >... baz.lst = lst >... return baz >... >>>> f = foo([1,2,3]) >>>> f[0] >Traceback (most recent call last): > File "<stdin>", line 1, in ? >TypeError: unsubscriptable object >>>> f.__getitem__(0) >1 >>>> > > >I thought x[y] and x.__getitem__(y) were supposed to always be >synonymous. Yes, but what was your "x"? Note:
>>> def foo(lst): ... class baz(object): ... def __getitem__(cls, idx): return cls.lst[idx] ... __getitem__ = classmethod(__getitem__) ... baz.lst = lst ... return baz ... >>> f = foo([1,2,3]) >>> f <class '__main__.baz'> Your "x" was the baz *class*, and the baz *class* is not subscriptable *itself*, even though it defines subscripting for its instances. To be ordinarily subscriptable, type(f).__getitem__ would have to succeed, which it doesn't: >>> type(f) <type 'type'> >>> type(f).__getitem__ Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: type object 'type' has no attribute '__getitem__' However, a baz instance is different: >>> finst = f() >>> finst <__main__.baz object at 0x02EF168C> Its type does have a __getitem__ attribute: >>> type(finst).__getitem__ <bound method type.__getitem__ of <class '__main__.baz'>> I think "bound method" is a bit of a misnomer for a classmethod, though it is a method, and it is bound, just to the class instead of the instance. (see below) >>> type(finst).__getitem__(0) 1 Or straightforward indexing syntax: >>> finst[0], finst[1], finst[2] (1, 2, 3) Contrast with the way an ordinary method repr's when you access it via class and instance: >>> class C(object): ... def ordinary_method(self): return 'Hi' ... >>> c=C() >>> C.ordinary_method <unbound method C.ordinary_method> >>> c.ordinary_method <bound method C.ordinary_method of <__main__.C object at 0x02EF164C>> >>> c.ordinary_method() 'Hi' >>> C.ordinary_method <unbound method C.ordinary_method> >>> C.ordinary_method(c) 'Hi' Note the difference between ordinary and classmethod: >>> type(c).ordinary_method <unbound method C.ordinary_method> >>> type(finst).__getitem__ <bound method type.__getitem__ of <class '__main__.baz'>> BTW, I see a class factory, but no "(meta)"class per se. Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list