22

In JavaScript we can do this:

var Color = {
    YELLOW: { value: 1, displayString: "Yellow" },
    GREEN: { value: 2, displayString: "Green" },
}

So I can call:

Color.YELLOW.displayString

In Java we can do this:

public enum Color {

    YELLOW (1, "Yellow"),
    GREEN (2, "Green"),

    private Color(String value, int displayString){
        this.value = value;
        this.displayString = displayString;
    }

    private final int value;
    private final String displayString;

    public String getValue() {return value;}
    public String getDisplayString() {return displayString;}
}

So I can call:

Color.YELLOW.getDisplayString()

After much research I haven't found a clean way to do this in Python using the built-in Enum module. How can I do this?

Thanks

1
  • The javascript is an object more closely related to a HashMap in Java. There is a Dictionary in python that might serve your purposes. Commented Feb 23, 2016 at 2:37

3 Answers 3

35

There are two concepts involved here: enumerations and attribute-style access to object members that can be initialised inline. For the latter, you'll need some kind of custom class, but since you want something very straightforward, a namedtuple is sufficient for that. So, combining namedtuple and enum, this could be a solution:

from enum import Enum
from collections import namedtuple

Color = namedtuple('Color', ['value', 'displayString'])

class Colors(Enum):

    @property
    def displayString(self):
        return self.value.displayString

    yellow = Color(1, 'Yellow')
    green = Color(2, 'Green')

print(Colors.yellow.displayString)
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you very much that is what I needed! Combined with the use of @property annotations we can access underlying values directly like this: Colors.yellow.displayString
Thank you for pointing this out, I've edited the answer to demonstrate it.
how to get an enum object by value? Is it working here!
i think yellow.value does not work here. Enum can be removed and value may be implemented with @property as a workaround. Then it is not enum anymore.
9

Here is another approach, that is the code from: https://github.com/hzdg/django-enumfields

import enum
import inspect

class ColorEnumMeta(enum.EnumMeta):
    def __new__(mcs, name, bases, attrs):
        DisplayStrings = attrs.get('DisplayStrings')

        if DisplayStrings is not None and inspect.isclass(DisplayStrings):
            del attrs['DisplayStrings']
            if hasattr(attrs, '_member_names'):
                attrs._member_names.remove('DisplayStrings')

        obj = super().__new__(mcs, name, bases, attrs)
        for m in obj:
            m.display_string = getattr(DisplayStrings, m.name, None)

        return obj

class Color(enum.Enum, metaclass=ColorEnumMeta):
    yellow = 1
    green = 2

    class DisplayStrings:
        yellow = 'Yellow'
        green = 'Green'

print(Color.yellow.display_string)  # 'Yellow'

or something that is based on this code, but a bit shorter:

import enum

class ColorEnumMeta(enum.EnumMeta):
    def __new__(mcs, name, bases, attrs):
        obj = super().__new__(mcs, name, bases, attrs)
        obj._value2member_map_ = {}
        for m in obj:
            value, display_string = m.value
            m._value_ = value
            m.display_string = display_string
            obj._value2member_map_[value] = m

        return obj

class Color(enum.Enum, metaclass=ColorEnumMeta):
    yellow = 1, 'Yellow'
    green = 2, 'Green'

print(Color.yellow.display_string)  # 'Yellow'

Comments

-7

You should normally never include literals like this in your code. The content should come from a file or database. But you can see how to build it up

>>> from collections import namedtuple
>>> Color = namedtuple("color", "YELLOW,GREEN")(
        namedtuple("yellow", "value,display_string")(1, "yellow"),
        namedtuple("green", "value,display_string")(2, "green"))
>>> Color.YELLOW.display_string
'yellow'

This also works for older Pythons that don't support enum

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.