【问题标题】:How to get all values from python enum class?如何从python枚举类中获取所有值?
【发布时间】:2015-06-12 17:50:37
【问题描述】:

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

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

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

【问题讨论】:

    标签: python enums


    【解决方案1】:

    我有一个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())
    

    我会像这样使用它:

    class Roles(SuperEnum):
        ADMIN = 1
        USER = 2
        GUEST = 3
    

    所以我可以:

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

    【讨论】:

      【解决方案2】:

      如果只是名称,请使用_member_names_ 以获得快速简单的结果,即

      Color._member_names_
      

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

      return list(map(lambda x: x.value, Color._member_map_.values()))
      

      将返回颜色的所有有效值

      【讨论】:

      • 被低估的答案。
      • 这是真正的答案,没有任何额外的行话或第三方枚举。开箱即用。
      • 这似乎有点脏,因为它使用了 Enum 类的私有属性。
      • @HosseyNJF _member_names_ 不是私有的,它只是一种魔法/dunder 方法。
      • @EliuX,你为什么要还原我的编辑?看来你还是自己改回来了……
      【解决方案3】:

      一种方法是获取_value2member_map_ 属性的键:

      class Color(Enum):
          RED = 1
          BLUE = 2
      
      list(Color._value2member_map_.keys())
      # [1, 2]
      

      【讨论】:

      • 还有._member_map_方法,在某些情况下可能有用。
      【解决方案4】:

      甜蜜而简单的做法是:

      from enum import Enum
      ENUM_VAR_NAME = Enum('ENUM_VAR_NAME',['var1',var2',var3'])
      
      ENUM_VAR_NAME.var1
      

      【讨论】:

        【解决方案5】:

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

        from enum import IntEnum
        
        class LogLevel(IntEnum):
            DEBUG = 0
            INFO = 1
            WARNING = 2
            ERROR = 3
        

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

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

        我发现使用枚举常量而不是整数更具表现力。如果枚举是从 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'
        

        【讨论】:

          【解决方案6】:

          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
          
          >>> role_names = RoleNames.list_roles()
          >>> print(role_names)
          

          或者如果您有多个 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"
          
          

          【讨论】:

            【解决方案7】:

            根据@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())
            

            生产:

            ['CREATE', 'STATUS', 'EXPAND', 'DELETE']
            

            【讨论】:

            • 这是非常 Pythonic 和优雅的答案。谢谢。
            • 漂亮!我一直在尝试这样做大约一个小时,但没有抓住对 classmethod 的需求。我试图只是子类化并添加一个属性属性,但无法让 super().__init__() 正确地将参数传递给 Enum。谢谢!
            【解决方案8】:

            class enum.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}
            

            【讨论】:

              【解决方案9】:

              要将 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())
              

              结果:

              [1, 'GREEN', ('blue', '#0000ff')]
              

              【讨论】:

              • 我会使用@classmethod 而不是@staticmethod
              • @ISONecroMAn 我猜@classmethod 需要创建Color 类的实例。这就是为什么staticmethod 在这里似乎是正确的选择。
              • @LeonidDashko 一点也不。看我的回答。
              • @LeonidDashko @dangoonfast 是正确的。您可以使用@classmethod 并改用return list(map(lambda c: c.value, cls))
              • 如果你有这么多枚举值,速度比可读性更重要,那么还有其他问题......
              【解决方案10】:

              所以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....但这只是一个实现细节,不应该被玩弄。黑魔法的代价是巨大的维护成本。

              【讨论】:

              • 只是一个侧边栏:可以将项目添加到__members__吗?允许extensions 从而创建新的Enum 成员将是一种有趣的方式。 ...顺便说一句,赞成为表格带来新的(to me)属性。
              • @IAbstract:不,这是不允许的。如果有人在创建 Enum 后找到了添加/减去成员的方法,他们可能会破坏该 Enum。
              • @IAbstract:事后添加新成员通常不是一个好主意。如果你真的想,请查看this answer
              【解决方案11】:

              您可以执行以下操作:

              [e.value for e in Color]
              

              【讨论】:

              • python 检查值是否在枚举中非常复杂,if foo in [e.value for e in Color]
              • @run_the_race 这不是很漂亮,但它更短:if foo in e.__members__.values()
              • @ori 您的示例没有意义,因为如果1 不在Color 中,它将失败。这样你就可以做到try: Color(1) except ValueError: ... 这实际上是非常pythonic
              【解决方案12】:

              你可以使用IntEnum:

              from enum import IntEnum
              
              class Color(IntEnum):
                 RED = 1
                 BLUE = 2
              
              
              print(int(Color.RED))   # prints 1
              

              获取整数列表:

              enum_list = list(map(int, Color))
              print(enum_list) # prints [1, 2]
              

              【讨论】:

              • 您使用第三方的。但它也说它有intenum
              • 我如何打印 [(1,'RED'), (2, 'BLUE')]
              • 这个怎么样:a = [(int(v), str(v)) for v in Color] 然后print(a)
              • 这个怎么样:[(color.value, color.name) for color in Color]
              • @vlad-ardelean 的评论是最好的和最 Pythonic 的。这是 Enum 类型的惯用用法,优雅且易读
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-01-17
              • 2020-01-12
              • 1970-01-01
              • 2021-12-15
              • 2010-12-05
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多