如何在 Python 的枚举中定义自定义属性(类 Javascript)

新手上路,请多包涵

在 JavaScript 中我们可以这样做:

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

所以我可以打电话:

 Color.YELLOW.displayString

在 Java 中我们可以这样做:

 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;}
}

所以我可以打电话:

 Color.YELLOW.getDisplayString()

经过大量研究,我还没有找到使用内置 Enum 模块在 Python 中执行此操作的干净方法。我怎样才能做到这一点?

谢谢

原文由 olivierr91 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

这里涉及到两个概念:枚举和对可以内联初始化的对象成员的属性式访问。对于后者,您需要某种自定义类,但由于您想要的东西非常简单,所以 namedtuple 就足够了。因此,结合 namedtupleenum ,这可能是一个解决方案:

 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)

原文由 Thomas Lotze 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是另一种方法,即来自的代码: 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'

或基于此代码但更短的内容:

 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'

原文由 Arany 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题