枚举函数用于将一个值映射到相关的值

4

目前,我有一个枚举来表示名称/数字映射。然而,每个事件类型还有其他“相关属性”(例如状态代码和消息类型)。

class EventType(Enum):
  CANCELLED = 0
  ONTIME = 1
  DELAYED = 2

  def get_status(self):
    if self == EventType.CANCELLED:
        return "statuscode1"
    elif self == EventType.DELAYED:
        return "statuscode2"
    else:
        return "statuscode3"

  def get_message_type(self):
    if self == EventType.CANCELLED:
        return "messagetype1"
    elif self == EventType.DELAYED:
        return "messagetype2"
    else:
        return "messagetype3"

除了创建上述方法并检查自身的大量if链外,是否有更简洁的重构方法来返回状态代码和消息类型?这就像是CANCELLED = (0, statuscode1, messagetype1).. 我该如何在枚举中表示这个概念?枚举甚至是正确的做法吗?


这是一个重复的问题吗?我已经在原帖中提供了表示枚举的代码。 - Dragan R.
我认为这是重复的,因为如果你看一些那个问题的顶级答案,你可以找到在Python中实现枚举的方法。 - Mr Alihoseiny
@MrAlihoseiny:OP并不是在询问如何实现枚举类型,而是如何使用现有的Enum类型。 - Ethan Furman
3个回答

4
如果你想让枚举成员的值为0、1或2,则需要重写__new__或使用aenum库。使用aenum1
from aenum import MultiValueEnum

class EventType(MultiValueEnum):
    _init_ = 'value status message'
    CANCELLED = 0, 'status1', 'message1'
    ONTIME = 1, 'status2', 'message2'
    DELAYED = 2, 'status3', 'message3'

并且在使用中:

>>> print(EventType.ONTIME)
EventType.ONTIME
>>> print(EventType.ONTIME.value)
1
>>> print(EventType.ONTIME.status)
status2
>>> print(EventType.ONTIME.message)
message2

查看this answer以了解如何使用stdlib枚举(它使用覆盖__new__技术)来实现此操作的示例。


1声明:我是Python标准库中Enum, enum34回退, 和 高级枚举(aenum) 库的作者。


最终采用了这种方法。另一种方法也很好,但这种方法似乎更容易些。谢谢! - Dragan R.

2
在Python 3.4中,有一种新的枚举数据类型Enum,可以这样使用:
class EventType(Enum):

    def __init__(self, id, code, message):
        self.id = id
        self.code = code
        self.message = message

    CANCELLED = 1, 'code1', 'message1'
    ONTIME = 2, 'code2', 'message2'
    DELAYED = 3, 'code3', 'message3

使用方法如下:

EventType.CANCELLED.code # returns 'message1'

如果只是你所描述的用例,你也可以使用命名元组:

from collections import namedtuple

    Event = namedtuple('event', ['id', 'code', 'message'])

    class EventType:
        CANCELLED = Event(1, 'code1', 'message1')
        ONTIME = Event(2, 'code2', 'message2')
        DELAYED = Event(3, 'code3', 'message3')

使用这个方法:
EventType.CANCELLED # return event(id=1, code='code1', message='message1')
EventType.CANCELLED.message # return message1

合理使用 __init__。但如果 OP 需要的值是 012,那么应该重写 __new__。请参考我的另一个答案中的示例。 - Ethan Furman

1

您可以将元组作为Enum对象的值,并将状态和消息字符串与整数代码一起包含在其中。然后,您可以添加方法(或property描述符)通过value属性获取元组中的各个部分:

class EventType(Enum):
   CANCELLED = 0, "status1", "message1"
   ONTIME = 1, "status2", "message2"
   DELAYED = 2, "status3", "message3"

   @property
   def code(self):
       return self.value[0]

   @property
   def status(self):
       return self.value[1]

   @property
   def message(self):
       return self.value[2]

print(EventType.CANCELLED.message) # prints "message3"

不错!但是这个方法会将member.value保留为元组而不是整数。 - Ethan Furman
我将尝试这种方法,以及上面的aenum方法答案。谢谢你们两个! - Dragan R.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接