__getitem__ method on (meta)classes

Steven Bethard steven.bethard at gmail.com
Wed Mar 16 09:15:11 CET 2005


Ron Garret wrote:
> In article <R4idnd0F2IMyvqrfRVn-1g at comcast.com>,
>  Steven Bethard <steven.bethard at gmail.com> wrote:
> 
>>>Yeah, except I actually left out one thing:  I also want type(v)==e1.
>>
>>Why?  In Python usually you rely on duck-typing and not explicit type 
>>checks.  What is it that you're trying to gain by asserting type(v) == e1?
> 
> Clarity.  I want to be able to distinguish a member of an enumeration 
> from a string or an integer for the same reason one would want to 
> distinguish 123 from "123".

So then you don't necessarily need that type(v) == e1, you just need 
type(v) != str.  How about:

py> class enum(object):
...     class item(object):
...         def __init__(self, val):
...             self.val = val
...         def __repr__(self):
...             return 'enum.item(%r)' % self.val
...     def __init__(self, vals):
...         self.items = [type(self).item(val) for val in vals]
...         self._val_item_map = dict(zip(vals, self.items))
...         self._index_item_map = dict(enumerate(self.items))
...     def __call__(self, val):
...         try:
...             return self._val_item_map[val]
...         except KeyError:
...             raise TypeError("%s is not a valid %s" % (val, type(self)))
...     def __getitem__(self, index):
...         return self._index_item_map[index]
...     def __iter__(self):
...         return iter(self.items)
...
py> e1 = enum(['a', 'b', 'c'])
py> e1('a')
enum.item('a')
py> e1('x')
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
   File "<interactive input>", line 15, in __call__
TypeError: x is not a valid <class '__main__.enum'>
py> e1[2]
enum.item('c')
py> list(e1)
[enum.item('a'), enum.item('b'), enum.item('c')]

Note that unlike your posted solution, the __getitem__ here returns 
enum.item objects intead of the strings.  Not sure which you intended 
here, but it should be easy enough to switch it the other way.  I've 
also added to auxiliary dicts to make lookup quicker.  (They also give 
you some more flexibility if you need to support other operations.)

STeVe



More information about the Python-list mailing list