¿Cómo obtener todos los valores de la clase python enum?

140

Estoy usando la biblioteca Enum4 para crear una clase enum de la siguiente manera:

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

Quiero imprimir [1, 2]como una lista en alguna parte. ¿Cómo puedo conseguir esto?

usuario1159517
fuente

Respuestas:

48

Puedes usar IntEnum :

from enum import IntEnum

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


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

Para obtener una lista de las entradas:

enum_list = list(map(int, Color))
print(enum_list) # prints [1, 2]
Marcin
fuente
Usas un tercero. Pero también dice que tiene intenum
Marcin
¿Cómo imprimo como [(1, 'ROJO'), (2, 'AZUL')]
user1159517
¿Qué pasa con esto? a = [(int(v), str(v)) for v in Color]Y luego print(a).
Marcin
34
¿Qué tal esto:[(color.value, color.name) for color in Color]
Vlad-ardelean
2
El comentario de @ vlad-ardelean es el mejor y más pitónico. Ese es el uso idiomático del tipo Enum, elegante y eminentemente legible
dusktreader
431

Puedes hacer lo siguiente:

[e.value for e in Color]
ozgur
fuente
1
@ user2340939 Eso devuelve la lista de enumeraciones, no la lista de valores. Si está de acuerdo con eso, también podría usarlist(Color)
endolito
1
Esto debe marcarse como la respuesta correcta.
SKYFALL26
22

Para usar Enum con cualquier tipo de valor, intente esto:
actualizado con algunas mejoras ... ¡Gracias @Jeff, por su consejo!

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
fuente
66
Usaría @classmethod en lugar de @ staticmethod
ISONecroMAn
1
@ISONecroMAn Supongo @classmethodque requeriría crear una instancia de Colorclase. Es por eso que staticmethodparece ser la elección correcta aquí.
Leonid Dashko
@LeonidDashko en absoluto. Mira mi respuesta.
blueFast
@LeonidDashko @dangoonfast es correcto. Puedes usar @classmethody usar return list(map(lambda c: c.value, cls))en su lugar.
Riptyde4
18

Basado en la respuesta de @Jeff, refactorizado para usar a classmethodpara que pueda reutilizar el mismo código para cualquiera de sus enumeraciones:

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

Produce:

['CREATE', 'STATUS', 'EXPAND', 'DELETE']
blueFast
fuente
7

La clase enum.Enumes una clase que resuelve todas sus necesidades de enumeración, por lo que solo necesita heredar de ella y agregar sus propios campos. Luego, a partir de entonces, todo lo que necesita hacer es llamar a sus 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
fuente
6

Entonces el Enumtiene un __members__dict. La solución que propuso @ozgur es realmente la mejor, pero puedes hacer esto, que hace lo mismo, con más trabajo

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

El __members__diccionario podría ser útil si desea insertar cosas dinámicamente en él ... en una situación loca.

[EDITAR] Aparentemente __members__no es un diccionario, sino un proxy de mapa. Lo que significa que no puede agregarle elementos fácilmente.

Sin embargo, puede hacer cosas extrañas como MyEnum.__dict__['_member_map_']['new_key'] = 'new_value', y luego puede usar la nueva clave como MyEnum.new_key... pero esto es solo un detalle de implementación, y no debe jugarse con él. La magia negra se paga con enormes costos de mantenimiento.

vlad-ardelean
fuente
Solo una barra lateral: ¿se pueden agregar elementos __members__? Sería una forma interesante de permitir extensiones creando así nuevos Enummiembros. ... por cierto, votó por traer un nuevo atributo ( para mí ) a la tabla.
IAbstract
@IAbstract: No, eso no está permitido. Si alguien descubre una forma de sumar / restar miembros después de que se crea la enumeración, probablemente romperá esa enumeración.
Ethan Furman
@IAbstract: Agregar nuevos miembros después de que el hecho no sea una buena idea. Si realmente quieres, mira esta respuesta .
Ethan Furman
1

Úselo _member_names_para obtener un resultado rápido y sencillo si solo se trata de los nombres, es decir

Color._member_names_

Además, tiene _member_map_que devuelve un diccionario ordenado de los elementos. Esta función devuelve a collections.OrderedDict, por lo que tiene Color._member_names_.items()y Color._member_names_.values()para jugar. P.ej

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

devolverá todos los valores válidos de Color

EliuX
fuente
-1

puedes usar la función 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
fuente