Como obter todos os valores da classe python enum?


140

Estou usando a biblioteca Enum4 para criar uma classe enum da seguinte maneira:

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

Quero imprimir [1, 2]como uma lista em algum lugar. Como posso conseguir isso?

Respostas:


48

Você pode usar o IntEnum :

from enum import IntEnum

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


print(int(Color.RED))   # prints 1

Para obter uma lista das entradas:

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

Você usa um de terceiros. Mas também diz que tem intenum
Marcin

Como eu imprimo como [(1, 'RED'), (2, 'BLUE')]
user1159517

Que tal isso: a = [(int(v), str(v)) for v in Color]e então print(a).
Marcin

34
Como sobre isso: #[(color.value, color.name) for color in Color]
vlad-ardelean

2
O comentário de @ vlad-ardelean é o melhor e mais pitônico. Desse uso idiomático do tipo Enum, elegante e eminentemente legível
dusktreader

431

Você pode fazer o seguinte:

[e.value for e in Color]

1
@ user2340939 Isso retorna a lista de enumerações, não a lista de valores. Se você está bem com isso, você também pode usarlist(Color)
endólito

1
Isso deve ser marcado como a resposta correta.
SKYFALL26

22

Para usar o Enum com qualquer tipo de valor, tente o seguinte:
Atualizado com algumas melhorias ... Obrigado @ Jeff, pela sua dica!

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

Como resultado:

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

6
Gostaria de usar @classmethod em vez de @ staticmethod
ISONecroMAn

1
@ISONecroMAn Acho que @classmethodseria necessário criar uma instância de Colorclasse. É por isso que staticmethodparece ser a escolha correta aqui.
Leonid Dashko

@LeonidDashko de jeito nenhum. Veja minha resposta.
blueFast

@LeonidDashko @dangoonfast está correto. Você pode usar @classmethode usar return list(map(lambda c: c.value, cls)).
usar o seguinte código

18

Com base na resposta de @Jeff, refatorado para usar a classmethodpara que você possa reutilizar o mesmo código para qualquer uma de suas enumerações:

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

Produz:

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

7

class enum.Enumé uma classe que resolve todas as suas necessidades de enumeração; portanto, você só precisa herdar dela e adicionar seus próprios campos. A partir de então, tudo o que você precisa fazer é chamar seus atributos: 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}

6

Então o Enumtem um __members__ditado. A solução que o @ozgur propôs é realmente a melhor, mas você pode fazer isso, o que faz a mesma coisa, com mais trabalho

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

O __members__dicionário pode ser útil se você quiser inserir coisas dinamicamente nele ... em alguma situação maluca.

[EDIT] Aparentemente, __members__não é um dicionário, mas um proxy de mapa. O que significa que você não pode adicionar itens facilmente a ele.

No entanto, você pode fazer coisas estranhas como MyEnum.__dict__['_member_map_']['new_key'] = 'new_value', e então você pode usar a nova chave como MyEnum.new_key.... mas isso é apenas um detalhe de implementação e não deve ser jogado com. A magia negra é paga com enormes custos de manutenção.


Apenas uma barra lateral: os itens podem ser adicionados __members__? Seria uma maneira interessante de permitir extensões , criando novos Enummembros. ... btw, votado por trazer um novo atributo ( para mim ) para a tabela.
IAbstract

@IAbstract: Não, isso não é permitido. Se alguém descobrir uma maneira de adicionar / subtrair membros após a criação do Enum, provavelmente quebrará esse Enum.
Ethan Furman

@IAbstract: Adicione novos membros depois que o fato geralmente não é uma boa ideia. Se você realmente quiser, confira esta resposta .
Ethan Furman

1

Use _member_names_para obter um resultado fácil e rápido se forem apenas os nomes, ou seja,

Color._member_names_

Além disso, você possui o _member_map_que retorna um dicionário ordenado dos elementos. Esta função retorna a collections.OrderedDict, então você tem Color._member_names_.items()e Color._member_names_.values()para brincar. Por exemplo

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

retornará todos os valores válidos de Color


-1

você pode usar a função iter ():

from enum import IntEnum

class Color(IntEnum):
   RED = 1
   BLUE = 2
l=[]
for i in iter(Color):
    l.append(i.value)
print(l)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.