如何在不使用 try/catch 的情况下测试 Python Enum 中是否存在 int 值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43634618/
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 do I test if int value exists in Python Enum without using try/catch?
提问by Nathan Kovner
Using the Python Enum class, is there a way to test if an Enum contains a specific int value without using try/catch?
使用 Python Enum 类,有没有办法在不使用 try/catch 的情况下测试 Enum 是否包含特定的 int 值?
With the following class:
使用以下课程:
from enum import Enum
class Fruit(Enum):
Apple = 4
Orange = 5
Pear = 6
How can I test for the value 6 (returning true), or the value 7 (returning false)?
如何测试值 6(返回 true)或值 7(返回 false)?
回答by hiro protagonist
test for values
测试值
variant 1
变体 1
note that an Enum
has a member called _value2member_map_
(which is undocumented and may be changed/removed in future python versions):
请注意, anEnum
有一个名为的成员_value2member_map_
(未记录在案,可能会在未来的 Python 版本中更改/删除):
print(Fruit._value2member_map_)
# {4: <Fruit.Apple: 4>, 5: <Fruit.Orange: 5>, 6: <Fruit.Pear: 6>}
you can test if a value is in your Enum
against this map:
你可以测试一个值是否在你的Enum
地图中:
5 in Fruit._value2member_map_ # True
7 in Fruit._value2member_map_ # False
variant 2
变体2
if you do not want to rely on this feature this is an alternative:
如果您不想依赖此功能,这是一种替代方法:
values = [item.value for item in Fruit] # [4, 5, 6]
or (probably better): use a set
; the in
operator will be more efficient:
或(可能更好):使用set
; 该in
运营商将更加有效:
values = set(item.value for item in Fruit) # {4, 5, 6}
then test with
然后用
5 in values # True
7 in values # False
add has_value
to your class
添加has_value
到您的班级
you could then add this as a method to your class:
然后,您可以将其作为方法添加到您的类中:
class Fruit(Enum):
Apple = 4
Orange = 5
Pear = 6
@classmethod
def has_value(cls, value):
return value in cls._value2member_map_
print(Fruit.has_value(5)) # True
print(Fruit.has_value(7)) # False
test for keys
测试钥匙
if you want to test for the names (and not the values) i would use _member_names_
:
如果你想测试名称(而不是值),我会使用_member_names_
:
'Apple' in Fruit._member_names_ # True
'Mango' in Fruit._member_names_ # False
回答by Reda Maachi
You could use Enum.__members__
- an ordered dictionary mapping names to members:
您可以使用Enum.__members__
-将名称映射到成员的有序字典:
In [12]: 'Apple' in Fruit.__members__
Out[12]: True
In [13]: 'Grape' in Fruit.__members__
Out[13]: False
回答by manu3d
Building on what Reda Maachi started:
建立在 Reda Maachi 开始的基础上:
6 in Fruit.__members__.values()
returns True
返回真
7 in Fruit.__members__.values()
returns False
返回假
回答by JianWei
Just check whether it's in Enum. _value2member_map_
只需检查它是否在 Enum. _value2member_map_
In[15]: Fruit._value2member_map_
Out[15]: {4: <Fruit.Apple: 4>, 5: <Fruit.Orange: 5>, 6: <Fruit.Pear: 6>}
In[16]: 6 in Fruit._value2member_map_
Out[16]: True
In[17]: 7 in Fruit._value2member_map_
Out[17]: False
回答by Alex Jolig
You could use __members__
special attributeto iterate over members:
您可以使用__members__
特殊属性来迭代成员:
from enum import Enum
class Fruit(Enum):
Apple = 4
Orange = 5
Pear = 6
@staticmethod
def has_value(item):
return item in [v.value for v in Connection.__members__.values()]
回答by Joshua Ryan
There's another one liner solution nobody has mentioned yet:
还有另一种没有人提到的单线解决方案:
is_value_in_fruit = any(f.value == value_to_check for f in Fruit)
Also, if you use IntEnum
instead of Enum
, (class Fruit(IntEnum)
) you can just do this
此外,如果您使用IntEnum
代替Enum
, ( class Fruit(IntEnum)
) 您可以这样做
is_value_in_fruit = any(f == value_to_check for f in Fruit)
回答by maciek
IntEnum
+ __members__
IntEnum
+ __members__
You could use IntEnum
and __members__
to achieve required behaviour:
您可以使用IntEnum
和__members__
来实现所需的行为:
from enum import IntEnum
class Fruit(IntEnum):
Apple = 4
Orange = 5
Pear = 6
>>> 6 in Fruit.__members__.values()
True
>>> 7 in Fruit.__members__.values()
False
Enum
+ list comprehension + .value
Enum
+ 列表理解 + .value
If you must/want stick to Enum
, you can do:
如果你必须/想要坚持Enum
,你可以这样做:
>>> 6 in [f.value for f in Fruit]
True
>>> 7 in [f.value for f in Fruit]
False
EAPF + ValueError
EAPF + ValueError
Or you can use easier to ask for forgiveness than permissionmethod:
或者你可以使用比许可更容易请求原谅的方法:
try:
Fruit(x)
except ValueError:
return False
else:
return True
回答by Konchog
Don't.
别。
If you are using Enum, you can test for enum with
如果您使用的是枚举,则可以使用
if isinstance(key, Fruit):
But otherwise, try.. is the pythonic way to test for enum. Indeed, for any break in the duck-typing paradigm.
但除此之外, try.. 是测试枚举的 Pythonic 方式。事实上,对于鸭子类型范式的任何突破。
The correct, and pythonic, way of testing for an int in an IntEnum is to give it a go and to catch a ValueError if there's a failure.
在 IntEnum 中测试 int 的正确和 Pythonic 方法是试一试并在出现故障时捕获 ValueError。
Many of the solutions proposed above are actively deprecated and will be disallowed by 3.8 ( "DeprecationWarning: using non-Enums in containment checks will raise TypeError in Python 3.8" )
上面提出的许多解决方案都被积极弃用,将被 3.8 禁止(“DeprecationWarning:在包含检查中使用非枚举将引发 Python 3.8 中的 TypeError”)
If you are really disinterested in keeping your code modern, then you can just use
如果你真的不想让你的代码保持现代,那么你可以使用
if key in Fruit: