92

I'm using the backported Enum functionality from python 3.4 with python 2.7:

> python --version
Python 2.7.6
> pip install enum34
# Installs version 1.0...

According to the documentation for Enums in python 3 (https://docs.python.org/3/library/enum.html#creating-an-enum), "Enumerations support iteration, in definition order". However, iteration is not happening in order for me:

>>> from enum import Enum
>>> class Shake(Enum):
...     vanilla = 7
...     chocolate = 4
...     cookies = 9
...     mint = 3
...     
>>> for s in Shake:
...     print(s)
...     
Shake.mint
Shake.chocolate
Shake.vanilla
Shake.cookies

Am I misunderstanding something, or is iteration in definition order just not supported in the backported versions of Enums yet? Assuming the latter, is there an easy way to force it to happen in order?

Mikko Ohtamaa
  • 82,057
  • 50
  • 264
  • 435
Troy
  • 21,172
  • 20
  • 74
  • 103

2 Answers2

122

I found the answer here: https://pypi.python.org/pypi/enum34/1.0.

For python <3.0, you need to specify an __order__ attribute:

>>> from enum import Enum
>>> class Shake(Enum):
...     __order__ = 'vanilla chocolate cookies mint'
...     vanilla = 7
...     chocolate = 4
...     cookies = 9
...     mint = 3
...     
>>> for s in Shake:
...     print(s)
...     
Shake.vanilla
Shake.chocolate
Shake.cookies
Shake.mint
Troy
  • 21,172
  • 20
  • 74
  • 103
  • 1
    FYI: The link no longer goes to relevant information. :( – Pod Oct 17 '16 at 14:15
  • 3
    @neuronet: The language features necessary for `Enum` to know anything about definition order don't exist in Python 2. Backward incompatibility is inevitable. – user2357112 Jun 26 '18 at 07:01
  • 2
    @PurpleIce Some people maintain Python production codebases which were started more than 10 years. Some people maintain codebases which have to use external libraries which were not ported to Python 2. They all may justifiably prioritise different things than catching up with the latest version of the language if the previous one works just fine for them. Issuing harsh (and frankly, rude) judgements about it is unhelpful. – quant_dev Apr 04 '19 at 08:52
1

use

__order__ 

to define the order of enums for python version less than 3 . It is not necessary in python3 but make sure the order which is supplied same as declared order otherwise it will give error:

TypeError: member order does not match _order_


import enum


class EXCHANGE(enum.Enum):
    __order__ = " EXCHANGE_NSE EXCHANGE_BSE EXCHANGE_NFO EXCHANGE_CDS EXCHANGE_BFO EXCHANGE_MCX EXCHANGE_BCD "
    EXCHANGE_NSE = "NSE"
    EXCHANGE_BSE = "BSE"
    EXCHANGE_NFO = "NFO"
    EXCHANGE_CDS = "CDS"
    EXCHANGE_BFO = "BFO"
    EXCHANGE_MCX = "MCX"
    EXCHANGE_BCD = "BCD"


if __name__ == "__main__":
    for ex in EXCHANGE:
        print(f"{ex.name} : {ex.value}")

Output:

EXCHANGE_NSE : NSE
EXCHANGE_BSE : BSE
EXCHANGE_NFO : NFO
EXCHANGE_CDS : CDS
EXCHANGE_BFO : BFO
EXCHANGE_MCX : MCX
EXCHANGE_BCD : BCD
Udesh
  • 2,415
  • 2
  • 22
  • 32