__getitem__ method on (meta)classes

Ron Garret rNOSPAMon at flownet.com
Tue Mar 15 01:14:35 EST 2005


In article <423643e7.805032315 at news.oz.net>,
 bokr at oz.net (Bengt Richter) wrote:

> On 14 Mar 2005 17:43:53 -0800, ron at flownet.com 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*,

But why not?  __getitem__ is a class method, not an instance method.

(You can treat that as a rhetorical question.  I know the answer already 
from other postings in this thread.)

> BTW, I see a class factory, but no "(meta)"class per se.

That's because I took out extraneous code to not distract from the 
problem I was having, and in the process took out all the useful stuff 
:-)

What I'm really trying to do is to create enumerated types such that if:

e1 = enum(lst) and v = e1(x)

then

(x in lst) and (e1[v] == x)

In other words, I want to map values onto their representations using 
the () operator, and representations onto their values using the [] 
operator.  That requires me to define the [] operator on the enumerated 
classes themselves.  So my actual code was:

def enum(vals):
  class enum(object):
    def __init__(self, val):
      try:
        self.val = type(self).vals.index(val)
      except:
        raise TypeError, "%s is not a valid %s" % (val, type(self))
    def __getitem__(self, index): return self.vals.index(index)
    __getitem__=classmethod(__getitem__)
  enum.vals = vals
  return enum


(Actually, what I'm really trying to do is create a whole hierarchy of 
static type descriptors and automatically generate database schema from 
those descriptors, but that's a story for another day.)

Thanks for all the responses.

rg



More information about the Python-list mailing list