具有属性的python枚举

2024-03-28 11:26:02 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑:

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

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

有没有办法使简单枚举的思想适应这种情况?(请参见this question)理想情况下,就像在Java中一样,我希望将其全部塞进一个类中。

Java模型:

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

Tags: selfstringinitdef情况itemsgreenblue
3条回答

Python 3.4有一个new Enum data type(已经backported as ^{}enhanced as ^{}1)。enum34aenum2都很容易支持您的用例:

[aenumpy2/3]

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

[enum34py2/3或stdlib enum3.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'

使用中:

--> EnumWithAttrs.BLUE
<EnumWithAttrs.BLUE: 1>

--> EnumWithAttrs.BLUE.a
'c'

1披露:我是Python stdlib ^{}^{} backportAdvanced Enumeration (^{})库的作者。

2aenum还支持NamedConstants和基于元类的NamedTuples

对于Python 3:

class Status(Enum):
    READY = "ready", "I'm ready to do whatever is needed"
    ERROR = "error", "Something went wrong here"

    def __new__(cls, *args, **kwds):
        obj = object.__new__(cls)
        obj._value_ = args[0]
        return obj

    # ignore the first param since it's already set by __new__
    def __init__(self, _: str, description: str = None):
        self._description_ = description

    def __str__(self):
        return self.value

    # this makes sure that the description is read-only
    @property
    def description(self):
        return self._description_

并且可以按类型将其用作标准枚举或工厂:

print(Status.READY)
# ready
print(Status.READY.description)
# I'm ready to do whatever is needed
print(Status("ready")) # this does not create a new object
# ready

使用namedtuple

from collections import namedtuple

Item = namedtuple('abitem', ['a', 'b'])

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

相关问题 更多 >