Seeing [snippet 1178](http://www.djangosnippets.org/snippets/1178/) reminded me that I also had a go at writing a Choices class at some point. I'm content with the result, but I doubt xgettext will discover your translation strings, which will no doubt be inconvenient.
Here it is anyway, in all its overly-complicated glory :-)
The following demo was pulled from the function's docstring tests.
>>> simple = Choices("one", "two", "three")
>>> simple
Choices(one=0, two=1, three=2)
>>> tuple(simple)
((0, u'ein'), (1, u'zwei'), (2, u'drei'))
>>> (0, _('one')) in simple
True
>>> simple.ONE
0
>>> hasattr(simple, 'FOUR')
False
Ordering just follows the order that positional arguments were given. Keyword arguments are ordered by their value at appear after positional arguments.
>>> [ key for key, val in simple ]
[0, 1, 2]
>>> Choices(one=1, two=2, three=3)
Choices(one=1, two=2, three=3)
A Mix of keyword and non-keyword arguments
>>> Choices("one", two=2, three=3)
Choices(one=0, two=2, three=3)
Automatically generated values (for "one" below) should not clash.
>>> Choices("one", none=0, three=1, four=2)
Choices(one=3, none=0, three=1, four=2)
Here is an example of combined usage, using different object types.
>>> combined = Choices(one=1, two="two", three=None, four=False)
>>> len(combined)
4
>>> (1, _('one')) in combined
True
>>> ('two', _('two')) in combined
True
>>> (None, _('three')) in combined
True
>>> (False, _('four')) in combined
True
And here is an empty choices set. Not sure why you would want this....
>>> empty = Choices()
>>> empty
Choices()