如何从python枚举类中获取所有值?

use*_*517 105 python enums

我正在使用Enum4库来创建一个枚举类,如下所示:

class Color(Enum):
    RED = 1
    BLUE = 2
Run Code Online (Sandbox Code Playgroud)

我想在[1, 2]某处打印列表.我怎样才能做到这一点?

ozg*_*gur 317

您可以执行以下操作:

[e.value for e in Color]
Run Code Online (Sandbox Code Playgroud)

  • @run_the_race 这不太漂亮,但更短:`if foo in e.__members__.values()` (9认同)
  • @PaulBissex 你的例子不起作用。`e.__members__.values()` 返回枚举对象的实例,而不是它们的值。 (7认同)
  • 对于 python 来说,检查一个值是否在枚举中非常复杂,“if foo in [e.value for e in Color]” (4认同)

Mar*_*cin 33

您可以使用IntEnum:

from enum import IntEnum

class Color(IntEnum):
   RED = 1
   BLUE = 2


print(int(Color.RED))   # prints 1
Run Code Online (Sandbox Code Playgroud)

获取整数列表:

enum_list = list(map(int, Color))
print(enum_list) # prints [1, 2]
Run Code Online (Sandbox Code Playgroud)

  • 怎么样:`[(color.value,color.name)颜色的颜色]` (19认同)
  • @vlad-ardelean 的评论是最好的,也是最 Python 的。这是 Enum 类型的惯用用法,优雅且可读性极佳 (3认同)

小智 33

只需使用:

[e.value for e in Color]
Run Code Online (Sandbox Code Playgroud)

生产:

[1, 2]

要获取名称,请使用:

[e.name for e in Color]
Run Code Online (Sandbox Code Playgroud)

生产:

['红蓝']


Eli*_*iuX 19

使用_member_names_一种快速简单的结果,如果它仅仅是个名字,即

Color._member_names_
Run Code Online (Sandbox Code Playgroud)

此外,您还拥有_member_map_返回元素的有序字典。此函数返回 a collections.OrderedDict,因此您可以使用Color._member_names_.items()Color._member_names_.values()。例如

return list(map(lambda x: x.value, Color._member_map_.values()))
Run Code Online (Sandbox Code Playgroud)

将返回 Color 的所有有效值

  • @EliuX 前导下划线不是表示每个 PEP 8 的非公开值吗?它也[未记录](https://docs.python.org/3/library/enum.html)。 (14认同)
  • 但这看起来有点脏,因为它使用了 Enum 类的私有属性。 (5认同)
  • 被低估的答案。 (3认同)
  • @HosseyNJF `_member_names_` 不是私有的,它只是一个 magic/dunder 方法。 (3认同)
  • @t3chb0t Python 决定将其设为“_”(私有,但不是私有内部)是一种选择,表示“除非您知道自己在做什么,否则不要使用它”。如果他们不希望我们使用私有方法,他们应该将它们设为“__”,或者也许 Python 应该具有实际的方法隐私 (3认同)

Jef*_*eff 18

要使用具有任何类型值的Enum,请尝试以下操作:
更新了一些改进...感谢@Jeff,在您的提示下!

from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 'GREEN'
    BLUE = ('blue', '#0000ff')

    @staticmethod
    def list():
        return list(map(lambda c: c.value, Color))

print(Color.list())
Run Code Online (Sandbox Code Playgroud)

结果:

[1, 'GREEN', ('blue', '#0000ff')]
Run Code Online (Sandbox Code Playgroud)

  • 我会使用@classmethod而不是@ staticmethod (4认同)
  • 如果您有如此多的枚举值,速度比可读性更重要,那么还有其他问题...... (4认同)
  • @ISONecroMAn 我猜 `@classmethod` 需要创建 `Color` 类的实例。这就是为什么“staticmethod”在这里似乎是正确的选择。 (3认同)

Mey*_*zad 18

classenum.Enum是一个解决你所有枚举需求的类,所以你只需要继承它,并添加你自己的字段。从那时起,您需要做的就是调用它的属性:name& value

from enum import Enum

class Letter(Enum):
   A = 1
   B = 2
   C = 3

print({i.name: i.value for i in Letter})
# prints {'A': 1, 'B': 2, 'C': 3}
Run Code Online (Sandbox Code Playgroud)


sup*_*odo 18

你可以点个SuperEnum赞:

from enum import Enum

class SuperEnum(Enum):    
    @classmethod
    def to_dict(cls):
        """Returns a dictionary representation of the enum."""
        return {e.name: e.value for e in cls}
    
    @classmethod
    def keys(cls):
        """Returns a list of all the enum keys."""
        return cls._member_names_
    
    @classmethod
    def values(cls):
        """Returns a list of all the enum values."""
        return list(cls._value2member_map_.keys())
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

class Roles(SuperEnum):
    ADMIN = 1
    USER = 2
    GUEST = 3
Run Code Online (Sandbox Code Playgroud)

所以你可以:

Roles.to_dict() # {'ADMIN': 1, 'USER': 2, 'GUEST': 3}
Roles.keys() # ['ADMIN', 'USER', 'GUEST']
Roles.values() # [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)


Fra*_*ank 8

如果您使用的是 StrEnum 或 IntEnum,只需使用内置的星号表达式来解包:

from enum import IntEnum
class Color(IntEnum):
    RED = 0
    GREEN = 1
colors = [*Color]
Run Code Online (Sandbox Code Playgroud)


bwl*_*289 7

使用classmethod__members__

class RoleNames(str, Enum):
    AGENT = "agent"
    USER = "user"
    PRIMARY_USER = "primary_user"
    SUPER_USER = "super_user"
    
    @classmethod
    def list_roles(cls):
        role_names = [member.value for role, member in cls.__members__.items()]
        return role_names
Run Code Online (Sandbox Code Playgroud)
class RoleNames(str, Enum):
    AGENT = "agent"
    USER = "user"
    PRIMARY_USER = "primary_user"
    SUPER_USER = "super_user"
    
    @classmethod
    def list_roles(cls):
        role_names = [member.value for role, member in cls.__members__.items()]
        return role_names
Run Code Online (Sandbox Code Playgroud)

或者如果您有多个Enum类并想要抽象classmethod

class BaseEnum(Enum):
    @classmethod
    def list_roles(cls):
        role_names = [member.value for role, member in cls.__members__.items()]
        return role_names


class RoleNames(str, BaseEnum):    
    AGENT = "agent"
    USER = "user"
    PRIMARY_USER = "primary_user"
    SUPER_USER = "super_user"
    

class PermissionNames(str, BaseEnum):
    READ = "updated_at"
    WRITE = "sort_by"
    READ_WRITE = "sort_order"

Run Code Online (Sandbox Code Playgroud)


小智 7

一种方法是获取房产的钥匙_value2member_map_

class Color(Enum):
    RED = 1
    BLUE = 2

list(Color._value2member_map_.keys())
# [1, 2]
Run Code Online (Sandbox Code Playgroud)

  • 这个答案值得更高 (2认同)

der*_*wie 6

给定一个基于标准 python3 Enum/IntEnum 类的枚举:

from enum import IntEnum

class LogLevel(IntEnum):
    DEBUG = 0
    INFO = 1
    WARNING = 2
    ERROR = 3
Run Code Online (Sandbox Code Playgroud)

可以执行以下操作来获取枚举常量列表:

>>> print(list(LogLevel))
[<LogLevel.DEBUG: 0>, <LogLevel.INFO: 1>, <LogLevel.WARNING: 2>, <LogLevel.ERROR: 3>]
Run Code Online (Sandbox Code Playgroud)

我发现使用枚举常量而不是整数更具表现力。如果枚举继承自 IntEnum,则所有枚举常量也是整数,并且可以在任何地方使用:

>>> level = LogLevel.DEBUG

>>> level == 0
True

>>> level == 1
False

>>> level == LogLevel.INFO
False

>>> level == LogLevel.DEBUG
True

>>> "%d" % level
'0'

>>> "%s" % level
'LogLevel.DEBUG'
Run Code Online (Sandbox Code Playgroud)


vla*_*ean 5

所以Enum有一个命令__members__。@ozgur提出的解决方案确实是最好的,但是您可以通过做更多的工作来完成此任务

[color.value for color_name, color in Color.__members__.items()]

__members__如果您想在字典中动态插入内容,该字典可能会派上用场...在某些疯狂的情况下。

[编辑] 显然__members__不是字典,而是地图代理。这意味着您不能轻松地向其中添加项目。

但是,您可以做一些奇怪的事情,例如MyEnum.__dict__['_member_map_']['new_key'] = 'new_value',然后可以使用新的密钥,例如MyEnum.new_key....,但这只是实现细节,不应使用。黑魔法需要付出巨大的维护费用。


dan*_*ast 5

根据@Jeff的回答,将其重构为使用,classmethod以便您可以对任何枚举重用相同的代码:

from enum import Enum

class ExtendedEnum(Enum):

    @classmethod
    def list(cls):
        return list(map(lambda c: c.value, cls))

class OperationType(ExtendedEnum):
    CREATE = 'CREATE'
    STATUS = 'STATUS'
    EXPAND = 'EXPAND'
    DELETE = 'DELETE'

print(OperationType.list())
Run Code Online (Sandbox Code Playgroud)

产生:

['CREATE', 'STATUS', 'EXPAND', 'DELETE']
Run Code Online (Sandbox Code Playgroud)

  • 为什么用地图让事情变得更加混乱呢?Guido 想删除它们,因为你可以更清楚地使用生成器做同样的事情。`[c.value for c in cls]` 是 Python 中的首选语法。(这里并不重要,但一个好处是避免额外的每项 lambda 调用和映射开销)。或者只是内置的“Enum._member_names_”。 (10认同)
  • 这是一个非常 Pythonic 和优雅的答案。谢谢。 (3认同)
  • 美丽的!我已经尝试这样做大约一个小时了,但没有抓住类方法的需要。我试图仅子类化并添加属性属性,但无法让 super().__init__() 正确地将参数传递给 Enum。谢谢! (2认同)
  • 使用这样的列表理解:“[e.value for e in Color]”会比 lambda 映射列表更好 (2认同)