如何获取枚举元素的名称?

69

我有一个这样定义的枚举:

def enum(**enums):
    return type('Enum', (), enums)

Status = enum(
       STATUS_OK=0,
       STATUS_ERR_NULL_POINTER=1, 
       STATUS_ERR_INVALID_PARAMETER=2)

我有一个返回Status枚举类型的函数。我该如何获取枚举值的名称而不仅是值本身?

>>> cur_status = get_Status()
>>> print(cur_status)
1

我希望获得STATUS_ERR_NULL_POINTER,而不是1


注意:如果使用Python标准库的enum.Enum,请参考此问题→如何在Python中将int转换为Enum?- Stack Overflow - user202729
5个回答

92
您需要循环遍历类属性以查找匹配的名称:
name = next(name for name, value in vars(Status).items() if value == 1)

生成器表达式遍历属性及其值(从vars()函数生成的字典中获取),然后返回第一个与值1匹配的属性。
枚举最好使用Python 3.4中可用的enum早期版本的后移兼容库进行建模。
from enum import Enum

class Status(Enum):
    STATUS_OK = 0
    STATUS_ERR_NULL_POINTER = 1 
    STATUS_ERR_INVALID_PARAMETER = 2

给您访问名称和值的权限:
name = Status(1).name  # gives 'STATUS_ERR_NULL_POINTER'
value = Status.STATUS_ERR_NULL_POINTER.value  # gives 1

58

2021年更新: 这些答案已经过时。使用Python的标准Enum类,

cur_status.name

将返回名称。(STATUS_ERR_NULL_POINTER)

查找已知名称的枚举:

s = Status['STATUS_ERR_NULL_POINTER']

2
问题不是关于Python的“Enum”,而是关于OP创建的一个问题。 - Ethan Furman
19
应该使用Python中的枚举(enum)。 - brandonscript
此回答并没有解决原帖问题,因为原帖中仅提供了值(1)而非枚举对象,所以(1).name是无效的(尽管其对其他人似乎有用)。 - user202729

3
你不需要循环遍历Enum类,只需访问_member_map_即可。
>>> Status._member_map_['STATUS_OK']
<Status.STATUS_OK: 0>

问题是通过值(在您的示例中为0)查找枚举。 - Nerman
1
这很有用,但是反过来了 :) - interestedparty333
问题与 Python 的 Enum 无关,而是由 OP 创建的。 - Ethan Furman

3

我不确定这个功能是在哪个Python版本中引入的,但是隐藏属性_value2member_map_可以提供你所需的内容。

class Status(Enum):
    STATUS_OK=0
    STATUS_ERR_NULL_POINTER=1
    STATUS_ERR_INVALID_PARAMETER=2

str(Status._value2member_map_[1])

输出:

'Status.STATUS_ERR_NULL_POINTER'

15
您可以简单地使用 Status(1).name - Merlin1896
哦,那就简单多了! - DeusXMachina
1
问题与 Python 的 Enum 无关,而是由 OP 创建的。 - Ethan Furman

0

出于某种原因,上述大多数方法对我都不起作用。所有方法都将枚举类型返回为整数。我正在使用Python 3.7。

在我的解决方案中,我定义了类函数来处理这个问题。虽然不是纯粹的Pythonic方式,但对我的情况足够好。

from enum import Enum
    
class Status(Enum):
    STATUS_OK = 0
    STATUS_ERR_NULL_POINTER = 1 
    STATUS_ERR_INVALID_PARAMETER = 2
    
    @classmethod
    def name(cls,val):
        return { v:k for k,v in dict(vars(cls)).items() if isinstance(v,int)}.get(val,None)

# test it
stat = Status.STATUS_OK
print(Status.name(stat))

输出:'STATUS_OK'

我们似乎是在给状态之后询问状态,但在我的情况下,这是在其他地方以编程方式设置的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接