Python 如何测试具有特定名称的 Enum 成员是否存在?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29795488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to test if an Enum member with a certain name exists?
提问by Trilarion
Using Python 3.4 I want to test whether an Enum class contains a member with a certain name.
使用 Python 3.4 我想测试 Enum 类是否包含具有特定名称的成员。
Example:
例子:
class Constants(Enum):
One = 1
Two = 2
Three = 3
print(Constants['One'])
print(Constants['Four'])
gives:
给出:
Constants.One
File "C:\Python34\lib\enum.py", line 258, in __getitem__
return cls._member_map_[name]
KeyError: 'Four'
I could catch the KeyError
and take the exception as indication of existence but maybe there is a more elegant way?
我可以抓住KeyError
并把异常作为存在的迹象,但也许有更优雅的方式?
采纳答案by vaultah
You could use Enum.__members__
- an ordered dictionary mapping names to members:
您可以使用Enum.__members__
-将名称映射到成员的有序字典:
In [12]: 'One' in Constants.__members__
Out[12]: True
In [13]: 'Four' in Constants.__members__
Out[13]: False
回答by pzp
I would say this falls under EAFP(Easier to ask for forgiveness than permission), a concept that is relatively unique to Python.
我会说这属于EAFP(请求宽恕比许可更容易),这是 Python 相对独特的概念。
Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.
请求宽恕比许可更容易。这种常见的 Python 编码风格假设存在有效的键或属性,并在假设证明为假时捕获异常。这种干净快速的风格的特点是存在许多 try 和 except 语句。该技术与许多其他语言(如 C)常见的 LBYL 风格形成对比。
This contrasts with LBYL(Look before you leap), which is what I think you want when you say you are looking for "a more elegant way."
这与LBYL(Look before you jump)形成对比,当你说你正在寻找“一种更优雅的方式”时,我认为这就是你想要的。
Look before you leap. This coding style explicitly tests for pre-conditions before making calls or lookups. This style contrasts with the EAFP approach and is characterized by the presence of many if statements.
In a multi-threaded environment, the LBYL approach can risk introducing a race condition between “the looking” and “the leaping”. For example, the code, if key in mapping: return mapping[key] can fail if another thread removes key from mapping after the test, but before the lookup. This issue can be solved with locks or by using the EAFP approach.
三思而后行。这种编码风格在调用或查找之前显式地测试先决条件。这种风格与 EAFP 方法形成对比,其特点是存在许多 if 语句。
在多线程环境中,LBYL 方法可能会在“寻找”和“跳跃”之间引入竞争条件。例如,如果另一个线程在测试之后但在查找之前从映射中删除键,则代码 if key in mapping: return mapping[key] 可能会失败。这个问题可以通过锁或使用 EAFP 方法来解决。
Therefore based on the documentation, it is actually better to use try
/except
blocks for your problem.
因此,根据文档,实际上最好使用try
/ except
blocks 来解决您的问题。
TL;DR
TL; 博士
Use try
/except
blocks to catch the KeyError
exception.
使用try
/except
块来捕获KeyError
异常。
回答by paultop6
Could use the following to test if the name exists:
可以使用以下内容来测试名称是否存在:
if any(x for x in Constants if x.name == "One"):
# Exists
else:
# Doesn't Exist
Of use x.value to test for the enum value:
使用 x.value 来测试枚举值:
if any(x for x in Constants if x.value == 1):
# Exists
else:
# Doesn't Exist
回答by Danilo Akamine
Just a quick tip, you can put these suggestions above as class method. For instance:
只是一个快速提示,您可以将这些建议作为类方法放在上面。例如:
class Constants(Enum):
One = 1
Two = 2
Three = 3
@classmethod
def has_key(cls, name):
return any(x for x in cls if x.name == name)
In order to use:
为了使用:
In [6]: Constants.has_key('One')
Out[6]: True
In [7]: Constants.has_key('Four')
Out[7]: False