bmargulies bmargulies - 4 months ago 22
Python Question

python enums with attributes


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 */


Python 3.4 has a new Enum data type (which has been backported as enum34). enum34's author has also released aenum which is advanced Enum classes, etc1. Both of these easily support your use case:

[aenum py2/3]

import aenum
class EnumWithAttrs(aenum.AutoNumberEnum):
    _init_ = 'a b'
    GREEN = 'a', 'b'
    BLUE = 'c', 'd'

[enum34 py2/3 or stdlib enum 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

1 aenum also supports NamedConstants and metaclass-based NamedTuples.