Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在不使用try/catch的情况下测试Python枚举中是否存在int值?_Python_Enums - Fatal编程技术网

如何在不使用try/catch的情况下测试Python枚举中是否存在int值?

如何在不使用try/catch的情况下测试Python枚举中是否存在int值?,python,enums,Python,Enums,使用PythonEnum类,有没有一种方法可以在不使用try/catch的情况下测试Enum是否包含特定的int值 在下列班级: from enum import Enum class Fruit(Enum): Apple = 4 Orange = 5 Pear = 6 如何测试值6(返回true)或值7(返回false)?您可以使用Enum.\uuuu成员\uuuu-: 测试值 变式1 请注意,Enum有一个名为\u value2member\u map\u的成员(

使用PythonEnum类,有没有一种方法可以在不使用try/catch的情况下测试Enum是否包含特定的int值

在下列班级:

from enum import Enum

class Fruit(Enum):
    Apple = 4
    Orange = 5
    Pear = 6

如何测试值6(返回true)或值7(返回false)?

您可以使用
Enum.\uuuu成员\uuuu
-:

测试值 变式1
请注意,
Enum
有一个名为
\u value2member\u map\u
的成员(该成员未记录,在未来的python版本中可能会更改/删除):

变式2 如果您不想依赖此功能,这是另一种选择:

values = [item.value for item in Fruit]  # [4, 5, 6]
或者(可能更好):使用
集合
;中的
操作符将更高效:

values = set(item.value for item in Fruit)  # {4, 5, 6}
然后用

5 in values  # True
7 in values  # False
has_value
添加到您的类中 然后,您可以将其作为方法添加到类中:

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
钥匙测试 如果您想测试名称(而不是值),我将使用
\u member\u names\u

'Apple' in Fruit._member_names_  # True
'Mango' in Fruit._member_names_  # False

只需检查它是否在
Enum中_值2成员映射

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
[15]中的
:水果。_值2成员地图_
Out[15]:{4:,5:,6:}
在[16]中:6在水果中。_值2成员地图_
Out[16]:对
在[17]中:7在水果中。_值2成员地图_
Out[17]:假

建立在Reda Maachi的基础上:

6 in Fruit.__members__.values() 
返回True

7 in Fruit.__members__.values()  

返回False(假)

不返回。

如果您使用的是Enum,则可以使用

     if isinstance(key, Fruit):
但如果不是这样的话,试试。。是测试枚举的Python方法。事实上,对于鸭子打字范式的任何突破

测试IntEnum中的int的正确的、类似python的方法是尝试一下,并在出现故障时捕获ValueError

上面提出的许多解决方案都已被弃用,并将被3.8禁止(“弃用警告:在包含检查中使用非枚举将在Python 3.8中引发TypeError”)

如果您真的对保持代码的现代感兴趣,那么您可以使用

if key in Fruit:
答案的一个版本:

试试看:
水果(val)
返回真值
除值错误外:
返回错误
您可以使用来迭代成员:

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 Fruit.__members__.values()]

还有另一个一行解决方案,但还没有人提到:

is_value_in_fruit = any(f.value == value_to_check for f in Fruit)
此外,如果您使用
IntEnum
而不是
Enum
,(
class-Fruit(IntEnum)
)您可以这样做

is_value_in_fruit = any(f == value_to_check for f in Fruit) 

IntEnum
+
成员

您可以使用
IntEnum
\uuuu成员\uuuu
实现所需的行为:

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
+列表理解+
.value

如果您必须/想要坚持使用
Enum
,可以执行以下操作:

>>> 6 in [f.value for f in Fruit]
True
>>> 7 in [f.value for f in Fruit]
False
EAPF+
值错误

或者你可以使用比许可更容易请求原谅的方法:


有一种方法可以让所有枚举都能够检查项目是否存在:

import enum 

class MyEnumMeta(enum.EnumMeta): 
    def __contains__(cls, item): 
        return item in [v.value for v in cls.__members__.values()] 

class MyEnum(enum.Enum, metaclass=MyEnumMeta): 
   FOO = "foo" 
   BAR = "bar"
现在,您可以进行简单的检查:

>>> "foo" in MyEnum
True
如果所有枚举值始终为同一类型(例如字符串),则更简单:

import enum 
 
class MyEnumMeta(enum.EnumMeta):  
    def __contains__(cls, item): 
        return item in cls.__members__.values()

class MyEnum(str, enum.Enum, metaclass=MyEnumMeta): 
    FOO = "foo" 
    BAR = "bar"
编辑:另一个版本,技术上最正确的版本:

import enum 

class MyEnumMeta(enum.EnumMeta): 
    def __contains__(cls, item): 
        try:
            cls(item)
        except ValueError:
            return False
        else:
            return True

class MyEnum(enum.Enum, metaclass=MyEnumMeta): 
   FOO = "foo" 
   BAR = "bar"

如果枚举有许多成员,这种方法可以更快,因为它不生成新列表,并且在找到给定值时停止遍历枚举:

any(水果中x的x.value==5)#正确
任意(水果中x的x.value==7)#错误
这个怎么样

从枚举导入枚举
水果类(枚举):
苹果=4
橙色=5
梨=6
has_苹果=4英寸[n.水果中的n值]
这样,您还可以执行以下操作:

在[n.水果中n的名称]中有\u apples=“Apple”

我只是将一个IntEnum转换为一个列表,并正常测试它:

from enum import IntEnum
class Foo(IntEnum):
    ONE = 1
    TWO = 2
    THREE = 3

print(1 in list(Foo))
True
print(4 in list(Foo))
False

问题是测试int值,而不是字符串。枚举中是否没有包含这些值的成员?这不是很奇怪吗?这与问题的方向相反。这对价值观不起作用!(用于“键”)回答者可能有
Apple=“Apple”
,所以他有相同的字母和字母箱用于键和值。。。如果你有
APPLE=“APPLE”
,那么
。\uuuuu成员\uuuuuuu
将导致
{'APPLE':,'GRAPE':}
我个人更喜欢第二种解决方案。谢谢。这两个建议都不是特别节省记忆或时间,尽管从这些方面来说也不是很重。在我的例子中,我正在使用标准库中的
HTTPStatus
enum,该库目前包含57个条目。我永远不会处理枚举中的整个值列表,缓存它们是我希望避免的事情。@无如果您担心速度,您可以为查找创建一个
集。这将使用一些额外的内存,但不是很大的内存量…为什么返回值周围有括号?必须使用
返回any(value==item.value[0]用于cls中的item)
使用Python3时枚举结构是否发生了更改?
\u value2member\u map\u
是未记录的功能,所以最好避免使用它。这看起来是一种非常干净的方式。不幸的是,当我测试这个(至少在Py3.7中)时,它不是那样工作的。export.\uuuu members\uuuuu.values()的计算结果为odict\u值([,]),上面对6和7的测试对我来说都返回False。但这返回true:
>>水果中的水果。橙色。_成员_uu.values()true
我想指出,这只适用于IntEnum。这个解决方案实际上是错误的。因为OP询问如何检查值是否在枚举中,例如6或7。这将始终返回false,因为枚举的所有成员实际上都不等于6或7。试试看,这个应该高很多。。。简单有效,谢谢!
>>> "foo" in MyEnum
True
import enum 
 
class MyEnumMeta(enum.EnumMeta):  
    def __contains__(cls, item): 
        return item in cls.__members__.values()

class MyEnum(str, enum.Enum, metaclass=MyEnumMeta): 
    FOO = "foo" 
    BAR = "bar"
import enum 

class MyEnumMeta(enum.EnumMeta): 
    def __contains__(cls, item): 
        try:
            cls(item)
        except ValueError:
            return False
        else:
            return True

class MyEnum(enum.Enum, metaclass=MyEnumMeta): 
   FOO = "foo" 
   BAR = "bar"
from enum import IntEnum
class Foo(IntEnum):
    ONE = 1
    TWO = 2
    THREE = 3

print(1 in list(Foo))
True
print(4 in list(Foo))
False