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?

user1159517
fonte

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]
Marcin
fonte
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]
ozgur
fonte
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')]
Jeff
fonte
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']
blueFast
fonte
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}
Meysam Azad
fonte
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.

vlad-ardelean
fonte
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

EliuX
fonte
-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)
Ali Shekari
fonte