How can I make this enum type support iteration?
python
Solution
The problem is that `type(…)` returns a type, i.e. something that’s actually used to create objects. Now of course you could argue if that’s a problem or not—and it’s likely not due to how Python’s typing system works (everything is an object, types are just objects of `type` objects etc.).
The effect however is that you can’t add special methods, like `__iter__` which would be needed in this case. Special methods are however looked up on the type of the object, so in this case on `type` (which is the base type of the type you’re creating). And `type`—as you would expect—is not iterable.
So if you want to have something iterable, you will need to create something that is not a type. You could probably come up with some fancy meta class here, but the easiest thing you can do, which also keeps your code at the same length, is really a named tuple. This is btw. also what the semantics in the Python 3.4 `enum` type is inspired by.
>>> def enum(*keys):
return namedtuple('Enum', keys)(*range(len(keys)))
>>> Suit = enum('spades', 'hearts', 'diamonds', 'clubs')
>>> Suit.spades
0
>>> Suit.hearts
1
>>> Suit.diamonds
2
>>> Suit.clubs
3
>>> [s for s in Suit]
[0, 1, 2, 3]
Problem
After this answer by Alec Thomas, I am using the following to create enumerations: ``` def enum(*sequential): enums = dict(zip(sequential, range(len(sequential)))) return type('Enum', (), enums) ``` I would like to be able to obtain the length of one of these enums. For example, I can write ``` >>> Suit = enum('spades', 'hearts', 'diamonds', 'clubs') >>> Suit.spades 0 >>> Suit.hearts 1 >>> Suit.diamonds 2 >>> Suit.clubs 3 ``` but there’s no way to list all of the enumeration values at runtime. I’d like to be able to do something like ``` >>> [s for s in Suit] [0, 1, 2, 3] ``` I’ve tried assigning `enum['__iter__']` within the `enum()` function, but I don’t know what kind of object I need to assign: ``` def enum(*sequential): enums = dict(zip(sequential, range(len(sequential)))) enums['__iter__'] = iter(range(len(sequential))) return type('Enum', (), enums) ``` gives ``` >>> [s for s in Suit] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'type' object is not iterable ``` How can I give an `enum` the ability to list its members? (Even just the ability for the enum to report its length would suffice, since then the members are simply the elements of `range(len(Suit))`.)