【问题标题】:Validate value is in Python Enum values验证值在 Python 枚举值中
【发布时间】:2019-06-05 04:45:15
【问题描述】:

我继承了类似这样的代码。

class Clients(IntEnum):
    ALICE = 1
    BOB = 2
    PETER = 3
    CHERYL = 4
    LARRY = 5

if client_id == 1:
    client_info = find_info(Clients.ALICE.value)
elif client_id == 2:
    client_info = find_info(Clients.BOB.value)
elif client_id == 3:
    client_info = find_info(Clients.PETER.value)
elif client_id == 4:
    client_info = find_info(Clients.CHERYL.value)
elif client_id == 5:
    client_info = find_info(Clients.LARRY.value)
else:
    raise Exception('Unknown client_id.')

对 Python 枚举没有太多经验,我迫切希望将其简化为类似这样的内容(伪代码):

if client_id in dict(Clients).keys():
    client_info = find_info(client_id)
else:
    raise Exception('Unknown client_id.')

我尝试了Clients.__members__Clients.__dict__,但它们的行为并不像我预期的那样,返回一个叫做mappingproxy 的东西。

我可以'ALICE' in Clients.__members__,但是这些值是否有等价物?如果没有,有没有更优雅的方式来编写这段代码?

【问题讨论】:

  • client_id 是否总是与客户的value 相同?如果是这样,您根本不需要映射,如enums allow access by value
  • 也许我应该稍微修改一下我的问题。我意识到我可以做到Clients(client_id).name 我想我的问题主要是如何验证价值。

标签: python enums


【解决方案1】:

您只能将值存储在普通元组(或列表)中,并使用枚举允许按值访问的事实:

values = tuple(item.value for item in Clients)

if client_id in values:
    # do something with Clients(client_id)
else:
    # print message or raise exception

或者您可以使用字典将值映射到枚举成员:

mapping = dict((item.value, item) for item in Clients)

if client_id in mapping:
    # do something with mapping[client_id]
else:
    # print message or raise exception

【讨论】:

  • 谢谢 - 最终使用列表 [item.value for item in Clients]
【解决方案2】:
try:
    client_info = find_info(Clients(client_id))
except ValueError:
    # customize error message
    raise Exception('Unknown client_id.')

【讨论】:

  • 我认为你是一个很好的人问:一般来说,有没有 Pythonic 偏好 if...else... 而不是 try...except...(反之亦然)?
  • @JoshFriedlander:如果可以引发异常,并且我不想自己修复它或以某种方式更改异常,那么我使用try/exceptif/else 用于测试不会引发异常或我不关心捕获它们的条件;同样,如果我不关心捕获任何东西,就这样做——所以上面将是client_info = find_info(Clients(client_id)),没有try/except,也没有if/else,如果指定了错误的值,则会引发ValueError('... is not a valid Clients')
猜你喜欢
  • 2010-09-06
  • 2017-12-14
  • 2021-05-16
  • 1970-01-01
  • 1970-01-01
  • 2017-07-03
  • 2019-12-29
  • 2018-05-29
  • 1970-01-01
相关资源
最近更新 更多