__getitem__ method on (meta)classes

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


In article <rNOSPAMon-E9EF21.22143514032005 at news.gha.chartermi.net>,
 Ron Garret <rNOSPAMon at flownet.com> wrote:

Wow, this is really cool:

> What I'm really trying to do is to create enumerated types...

And the code I ended up with is:

# Inheriting from type, not object, is the key:
class enum_metaclass(type):
  def __getitem__(self, index):
    return self.vals[index]

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


So now I can do, e.g.:

>>> e1 = enum(['a','b','c'])
>>> e1('a')
<__main__.enum object at 0x393c50>
>>> e1('x')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 8, in __init__
TypeError: x is not a valid <class '__main__.enum'>
>>> 

But I can also do this:

>>> for x in e1: print x
... 
a
b
c
>>> 

Note that there's no __iter__ method anywhere!  It makes an interesting 
little puzzle to figure out why this works.  (It totally blew me away 
when I first tried it.  Took me about five minutes of head scratching to 
figure it out.)

rg



More information about the Python-list mailing list