Search code examples
pythonenums

python enums with attributes


Consider:

class Item:
   def __init__(self, a, b):
       self.a = a
       self.b = b

class Items:
    GREEN = Item('a', 'b')
    BLUE = Item('c', 'd')

Is there a way to adapt the ideas for simple enums to this case? (see this question) Ideally, as in Java, I would like to cram it all into one class.

Java model:

enum EnumWithAttrs {
    GREEN("a", "b"),
    BLUE("c", "d");

    EnumWithAttrs(String a, String b) {
      this.a = a;
      this.b = b;
    }

    private String a;
    private String b;

    /* accessors and other java noise */
}

Solution

  • Python 3.4 has a new Enum data type (which has been backported as enum34 and enhanced as aenum1). Both enum34 and aenum2 easily support your use case:

    • aenum (Python 2/3)

        import aenum
        class EnumWithAttrs(aenum.AutoNumberEnum):
            _init_ = 'a b'
            GREEN = 'a', 'b'
            BLUE = 'c', 'd'
      
    • enum34 (Python 2/3) or standard library enum (Python 3.4+)

        import enum
        class EnumWithAttrs(enum.Enum):
      
            def __new__(cls, *args, **kwds):
                value = len(cls.__members__) + 1
                obj = object.__new__(cls)
                obj._value_ = value
                return obj
            def __init__(self, a, b):
                self.a = a
                self.b = b
      
            GREEN = 'a', 'b'
            BLUE = 'c', 'd'
      

    And in use:

    >>> EnumWithAttrs.BLUE
    <EnumWithAttrs.BLUE: 1>
    
    >>> EnumWithAttrs.BLUE.a
    'c'
    

    1 Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

    2 aenum also supports NamedConstants and metaclass-based NamedTuples.