【问题标题】:Enum function to map value to a related value枚举函数将值映射到相关值
【发布时间】:2018-10-11 17:14:18
【问题描述】:

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

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).. 我怎样才能在枚举中表示这个概念?枚举甚至是正确的方法吗?

【问题讨论】:

  • 怎么是重复的问题?我已经有代表 OP 中的枚举的代码...
  • 我认为它是重复的,因为如果您看到该问题的一些热门答案,您可以找到在 python 中实现枚举的方法。
  • @MrAlihoseiny:OP 不是在问如何实现枚举类型,而是如何使用现有的Enum 类型。跨度>

标签: python python-3.x enums


【解决方案1】:

如果您希望Enum 成员的值为012,则需要覆盖__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 stdlib Enumenum34 backportAdvanced Enumeration (aenum) 库的作者。

【讨论】:

  • 最终采用了这种方法。另一种方法也很好很干净,但是这种方法似乎更容易一些。谢谢!
【解决方案2】:

在 Python 3.4 中,有一个新的Enum data type,您可以将其用作:

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__。有关示例,请参见 my other answere here
【解决方案3】:

您可以使用元组作为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 保留为元组,而不是 int
  • 我要试试这个方法,以及上面的aenum方法答案。谢谢你们!
猜你喜欢
  • 1970-01-01
  • 2019-04-09
  • 2016-06-09
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 2016-03-16
  • 2011-11-15
  • 1970-01-01
相关资源
最近更新 更多