4 ms·
Enumerations support iteration, in definition order: >>> class Shake(Enum): ... vanilla = 7 ... chocolate = 4 ... cookies = 9 ... mint = 3
by marmaduke 13y ago
Enumerations support iteration, in definition order:
>>> class Shake(Enum):
... vanilla = 7
... chocolate = 4
... cookies = 9
... mint = 3
...
>>> for shake in Shake:
... print(shake)
...
Shake.vanilla
Shake.chocolate
Shake.cookies
Shake.mint
Python's execution model sez that the class declaration is nothing more
than code that is exec'd in a dictionary. We know that Python dictionaries
do not perserve order, so why is this iteration in definition order
possible, barring modification to the interpreter or dict type ?
- shoyer 13y agoThere is an OrderedDict class in the collections module of standard library. Enums store their members in a special __members__ attribute, which is such an OrderedDict. See this section of the PEP: http://www.python.org/dev/peps/pep-0435/#duplicating-enum-members-and-values http://www.python.org/dev/peps/pep-0435/#duplicating-enum-me...
- marmaduke 13y agoYou more or less ignored the contents of my comment w.r.t. execution model. I am well aware of OrderedDict, and I still do not understand how this behavior is possible unless Python 3 differs from 2 in the kind of dictionary used in code block executions.
- saidajigumi 13y agoThere's no need to modify the interpreter. Redefining __dict__ to support ordering would be enough, or perhaps defining a purpose-built __metaclass__[1]. [1] http://stackoverflow.com/a/6581949/183481 http://stackoverflow.com/a/6581949/183481
- marmaduke 13y agoNo-go on metaclass, the received type for metaclass __new__ method's members argument is a plain dict. Unless this is changed in Py 3, I still don't understand how this works.
- saidajigumi 13y agoHere's an example from the Python 3 docs[1] that specifically uses metaclass for exactly this scenario: class OrderedClass(type): @classmethod def __prepare__(metacls, name, bases, **kwds): return collections.OrderedDict() def __new__(cls, name, bases, namespace, **kwds): result = type.__new__(cls, name, bases, dict(namespace)) result.members = tuple(namespace) return result class A(metaclass=OrderedClass): def one(self): pass def two(self): pass def three(self): pass def four(self): pass >>> A.members ('__module__', 'one', 'two', 'three', 'four') [1] http://docs.python.org/3/reference/datamodel.html#metaclass-example http://docs.python.org/3/reference/datamodel.html#metaclass-...
- eliben 13y agoIt's possible by using a __prepare__ method in the metaclass of Enum, which allows to return an essentially ordered dict for the __dict__ of enumeration classes.
- marmaduke 13y agoI guess this is new to Py 3k? Thanks for the tip!
- paul_odin 13y agoRight, PEP 3115. Indeed one of the reasons is that "there is an important body of use cases where it would be useful to preserve the order in which a class members are declared." http://www.python.org/dev/peps/pep-3115/ http://www.python.org/dev/peps/pep-3115/