如何测试具有特定名称的Enum成员是否存在?

Tri*_*ion 18 python enums python-3.x

使用Python 3.4我想测试Enum类是否包含具有特定名称的成员.

例:

class Constants(Enum):
    One = 1
    Two = 2
    Three = 3

print(Constants['One'])
print(Constants['Four'])
Run Code Online (Sandbox Code Playgroud)

得到:

Constants.One
  File "C:\Python34\lib\enum.py", line 258, in __getitem__
    return cls._member_map_[name]
KeyError: 'Four'
Run Code Online (Sandbox Code Playgroud)

我可以抓住KeyError并将异常作为存在的指示,但也许有更优雅的方式?

vau*_*tah 36

您可以使用Enum.__members__- 将名称映射到成员的有序字典:

In [12]: 'One' in Constants.__members__
Out[12]: True

In [13]: 'Four' in Constants.__members__
Out[13]: False
Run Code Online (Sandbox Code Playgroud)


pzp*_*pzp 20

我会说这属于EAFP(更容易要求宽恕而非许可),这是一个相对独特的Python概念.

比许可更容易请求宽恕.这种常见的Python编码风格假设存在有效的键或属性,并且如果假设被证明是错误则捕获异常.这种干净和快速的风格的特点是存在许多try和except语句.该技术与许多其他语言(如C)共有的LBYL风格形成对比.

这与LBYL(跳跃前看)相反,当你说你正在寻找"更优雅的方式"时,这就是我想你想要的.

三思而后行.这种编码风格在进行调用或查找之前明确地测试前置条件.这种风格与EAFP方法形成对比,其特点是存在许多if语句.

在多线程环境中,LBYL方法可能会在"外观"和"跳跃"之间引入竞争条件.例如,代码,如果映射中的键:如果另一个线程在测试之后但在查找之前从映射中删除了键,则返回映射[key]可能会失败.可以使用锁定或使用EAFP方法解决此问题.

因此,基于文档,实际上最好使用try/ exceptblocks来解决您的问题.

TL; DR

使用try/ exceptblocks来捕获KeyError异常.

  • 在很多情况下,EAFP是正确的方法,但我不认为这是其中之一.`in`运算符恰好存在于想要检查`some_container`中的项目的情况. (4认同)
  • @EthanFurman枚举的in是对值而不是名称起作用。 (2认同)

Dan*_*ine 12

为了提高易读性,您可以将这些建议作为类方法放在上面。例如:

class Constants(Enum):
    One = 1
    Two = 2
    Three = 3

    @classmethod
    def has_key(cls, name):
        return name in cls.__members__ # solution above 1
        # return any(x for x in cls if x.name == name) # or solution above 2
Run Code Online (Sandbox Code Playgroud)

为了使用:

In [6]: Constants.has_key('One')
Out[6]: True

In [7]: Constants.has_key('Four')
Out[7]: False
Run Code Online (Sandbox Code Playgroud)


pau*_*op6 8

可以使用以下内容来测试名称是否存在:

if any(x for x in Constants if x.name == "One"):
  # Exists
else:
  # Doesn't Exist
Run Code Online (Sandbox Code Playgroud)

使用 x.value 来测试枚举值:

if any(x for x in Constants if x.value == 1):
  # Exists
else:
  # Doesn't Exist
Run Code Online (Sandbox Code Playgroud)