具有复杂类型的Python枚举

时间:2017-01-05 11:03:05

标签: python enums

我有Enum类型:

 class SystemCommands(Enum):
    Get_FW_version = (0, 1)
    Get_MAC_address = (1,1)
    Set_MAC_address = (2,7)
    Get_IP_addr = (3,1)
    Set_IP_addr = (4,5)
    Get_server_IP_addr = (5,1)
    Set_server_IP_addr = (6,5)
    Get_subnet_Mask = (7,1)
    Set_subnet_Mask = (8,5)
    Get_Gateway_Address = (9,1)
    Set_Gateway_Address = (10,5)
    Welcome = (16,1)
    Request_Cannot_Served = (17,1)

    def __init__(self, CommandCode, length):
        self.CommandCode = CommandCode
        self.length = length

我想创建一个仅基于int值的枚举变量:

code =10
...
Request = SystemCommands(code)

当然,我有一个很好的选择:

 raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 10 is not a valid SystemCommands

问题:如何仅基于一个值创建复杂类型的枚举?

4 个答案:

答案 0 :(得分:0)

来自文档,

  

如果您的枚举定义了__new__()和/或__init__(),那么无论如何   给予枚举成员的价值将被传递给那些   方法

所以你不能传递任意值,你需要传递一个有效的枚举成员值,比如说(10,5)

code = 10, 5
Request = SystemCommands(code)
print(Request)
# SystemCommands.Set_Gateway_Address

答案 1 :(得分:0)

from enum import Enum
class SystemCommands(Enum):
  Get_FW_version = (0, 1)
  Get_MAC_address = (1,1)
  Set_MAC_address = (2,7)
  Get_IP_addr = (3,1)
  Set_IP_addr = (4,5)
  Get_server_IP_addr = (5,1)
  Set_server_IP_addr = (6,5)
  Get_subnet_Mask = (7,1)
  Set_subnet_Mask = (8,5)
  Get_Gateway_Address = (9,1)
  Set_Gateway_Address = (10,5)
  Welcome = (16,1)
  Request_Cannot_Served = (17,1)

  def __init__(self, CommandCode, length):
      self.CommandCode = CommandCode
      self.length = length

# Moses is right but you can also do something like that (workaround)
# use @unique to protect duplicates
code = 10
for val in SystemCommands:
  if val.value[0] == code:
    print (val)

# SystemCommands.Set_Gateway_Address

答案 2 :(得分:0)

谢谢Ari,我修改了你的答案,更加面向对象:

D:\apache-jena-3.1.1\lib\*

所以现在我可以像这样使用它:

class SystemCommands(Enum):
    Get_FW_version = (0, 1)
    Get_MAC_address = (1,1)
    Set_MAC_address = (2,7)
    Get_IP_addr = (3,1)
    Set_IP_addr = (4,5)
    Get_server_IP_addr = (5,1)
    Set_server_IP_addr = (6,5)
    Get_subnet_Mask = (7,1)
    Set_subnet_Mask = (8,5)
    Get_Gateway_Address = (9,1)
    Set_Gateway_Address = (10,5)
    Welcome = (16,1)
    Request_Cannot_Served = (17,1)

    def __init__(self, CommandCode, length):
        self.CommandCode = CommandCode
        self.length = length

    def getCommand(code):
        for val in SystemCommands:
            if code == val.CommandCode:
                return (val)

答案 3 :(得分:0)

如果要将多个值传递给Enum构造函数但只有其中一个是实际值,则需要编写your own __new__ method

# using enum34 or the stdlib Enum

from enum import Enum

class SystemCommands(Enum):
    Get_FW_version = (0, 1)
    Get_MAC_address = (1,1)
    Set_MAC_address = (2,7)

    def __new__(cls, CommandCode, length):
        member = object.__new__(cls)
        member._value_ = CommandCode
        member.length = length
        return member

然后

code = ...
request = SystemCommands(code)
print(request)
print(request.name)
print(request.value)
print(request.length)

如果可以使用aenum 1 库,那么这个过程会非常容易:

from aenum import Enum

class SystemCommands(Enum):
    _init_ = 'value length'
    Get_FW_version = 0, 1
    Get_MAC_address = 1,1
    Set_MAC_address = 2,7

1 披露:我是Python stdlib Enumenum34 backportAdvanced Enumeration (aenum)图书馆的作者。