问题
I have en Enum type:
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
I would like to create an enum variable based only on an int value:
code =10
...
Request = SystemCommands(code)
Of course i got a nice excpetion:
raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 10 is not a valid SystemCommands
Question: How can I create a complex-typed enum based only one value?
回答1:
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:
From the docs,
if your enumeration defines
__new__()
and/or__init__()
then whatever value(s) were given to the enum member will be passed into those methods.
So you can't pass an arbitrary value, you'll need to pass a valid enum member value, say (10, 5)
code = 10, 5
Request = SystemCommands(code)
print(Request)
# SystemCommands.Set_Gateway_Address
回答3:
If you want to pass multiple values to the Enum constructor but only have one of them be the actual value, then you need to write 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
and then
code = ...
request = SystemCommands(code)
print(request)
print(request.name)
print(request.value)
print(request.length)
The process is considerable easier if can use the aenum1 library:
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 Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.
回答4:
Thank you Ari, I modified your answer, to be a little more Object Oriented:
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)
So now i can use it like this:
Request = SystemCommands.getCommand(code)
print(Request.name)
来源:https://stackoverflow.com/questions/41483331/python-enum-with-complex-type