2017-03-16 143 views
3

當使用Python 3 programmatically中介紹的Enum類時,程序員應該如何檢查給定整數的枚舉成員?Python枚舉類成員

顯然,你可能只是ask for forgiveness,但是有沒有會員檢查功能,否則我錯過了?更明確地說,我想採取一個整數值,並檢查它的值是否對應於一個有效的枚舉。

from enum import Enum 

class TestEnum(Enum): 
    a = 0 
    b = 1 
    c = 2 

輸出:

In [13]: TestEnum(0) 
Out[13]: <TestEnum.a: 0> 

In [14]: TestEnum(4) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-14-09c663e9e214> in <module>() 
----> 1 TestEnum(4) 

C:\Anaconda3\lib\enum.py in __call__(cls, value, names, module, qualname, type, start) 
    239   """ 
    240   if names is None: # simple value lookup 
--> 241    return cls.__new__(cls, value) 
    242   # otherwise, functional API: we're creating a new Enum type 
    243   return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start) 

C:\Anaconda3\lib\enum.py in __new__(cls, value) 
    474     if member._value_ == value: 
    475      return member 
--> 476   raise ValueError("%r is not a valid %s" % (value, cls.__name__)) 
    477 
    478  def __repr__(self): 

ValueError: 4 is not a valid TestEnum 
+1

據我所知,只要'TestEnum'派生自'enum.IntEnum',就可以在TestEnum .__成員__。values()中嘗試'4'。 – farsil

+0

@farsil,把你的評論作爲答案,我會標記它的答案,如果沒有後續更漂亮的方式 –

回答

3

枚舉確實有__contains__方法,但它會檢查成員的名字,而不是成員的值:

def __contains__(cls, member): 
    return isinstance(member, cls) and member._name_ in cls._member_map_ 

內部(在CPython的),他們也有一個值映射到名字的私人屬性(會只爲可哈希值的工作,雖然):

>>> 2 in TestEnum._value2member_map_ 
True 
>>> 3 in TestEnum._value2member_map_ 
False 

但它不是一個好主意,依靠私有屬性,因爲他們可以在任何時候改變,因此你可以添加自己的方法,它遍歷__members__.values()

>>> class TestEnum(Enum): 
...  a = 0 
...  b = 1 
...  c = 2 
... 
...  @classmethod 
...  def check_value_exists(cls, value): 
...   return value in (val.value for val in cls.__members__.values()) 
... 

>>> 
>>> TestEnum.check_value_exists(2) 
True 
>>> TestEnum.check_value_exists(3) 
False 
0

你的意思是:

from enum import Enum 

class TestEnum(Enum): 
    a = 3 
    b = 2 
    c = 1 


print(TestEnum.b.name,TestEnum.b.value) 

或者

print(TestEnum(2).name,TestEnum(2).value) 

輸出:

B 2