Ron said:
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".[/QUOTE]
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