Używam biblioteki Enum4 do tworzenia klasy wyliczeniowej w następujący sposób:
class Color(Enum):
RED = 1
BLUE = 2
Chcę [1, 2]
gdzieś wydrukować jako listę. Jak mogę to osiągnąć?
Używam biblioteki Enum4 do tworzenia klasy wyliczeniowej w następujący sposób:
class Color(Enum):
RED = 1
BLUE = 2
Chcę [1, 2]
gdzieś wydrukować jako listę. Jak mogę to osiągnąć?
Odpowiedzi:
Możesz użyć IntEnum :
from enum import IntEnum
class Color(IntEnum):
RED = 1
BLUE = 2
print(int(Color.RED)) # prints 1
Aby uzyskać listę int:
enum_list = list(map(int, Color))
print(enum_list) # prints [1, 2]
a = [(int(v), str(v)) for v in Color]
a potem print(a)
.
[(color.value, color.name) for color in Color]
Aby użyć Enum z dowolnym typem wartości, spróbuj tego:
Zaktualizowany o kilka ulepszeń ... Dzięki @Jeff, twoja wskazówka!
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())
W wyniku:
[1, 'GREEN', ('blue', '#0000ff')]
@classmethod
że wymagałoby to stworzenia instancji Color
klasy. Dlatego staticmethod
wydaje się, że jest to właściwy wybór.
@classmethod
i użyć return list(map(lambda c: c.value, cls))
zamiast tego.
Color.__members__.values()
zamiast Koloru w map()
rozmowie da od razu 30% doładowanie. Możesz wtedy uzyskać nieco większą prędkość, zastępując lambdę przez operator.attrgetter('value')
.
Na podstawie odpowiedzi @Jeff, refaktoryzowano, aby użyć a classmethod
, aby można było ponownie użyć tego samego kodu dla dowolnego ze swoich wyliczeń:
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())
Produkuje:
['CREATE', 'STATUS', 'EXPAND', 'DELETE']
class enum.Enum
to klasa, która rozwiązuje wszystkie Twoje potrzeby związane z wyliczaniem, więc musisz po prostu dziedziczyć po niej i dodać własne pola. Od tego momentu wszystko, co musisz zrobić, to po prostu wywołać jego atrybuty: 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}
Więc Enum
ma __members__
dyktando. Rozwiązanie zaproponowane przez @ozgur jest naprawdę najlepsze, ale możesz to zrobić, co robi to samo, przy większej ilości pracy
[color.value for color_name, color in Color.__members__.items()]
__members__
Słownik mógłby się przydać, jeśli chcesz wstawić rzeczy dynamicznie w nim ... w jakiejś szalonej sytuacji.
[EDYCJA]
Najwyraźniej __members__
nie jest słownikiem, ale mapą proxy. Co oznacza, że nie możesz łatwo dodawać do niego elementów.
Możesz jednak robić dziwne rzeczy, takie jak MyEnum.__dict__['_member_map_']['new_key'] = 'new_value'
, a potem możesz użyć nowego klucza, takiego jak MyEnum.new_key
.... ale to tylko szczegół implementacji i nie powinno się nim bawić. Za czarną magię płacą ogromne koszty utrzymania.
__members__
? Byłby to interesujący sposób na zezwolenie na rozszerzenia, tworząc w ten sposób nowych Enum
członków. ... przy okazji, głosowano za wprowadzeniem nowego ( dla mnie ) atrybutu do tabeli.
Użyj, _member_names_
aby szybko uzyskać łatwy wynik, jeśli są to tylko nazwy, tj
Color._member_names_
Masz również, _member_map_
który zwraca uporządkowany słownik elementów. Funkcja ta zwraca collections.OrderedDict
, więc trzeba Color._member_names_.items()
i Color._member_names_.values()
do zabawy. Na przykład
return list(map(lambda x: x.value, Color._member_map_.values()))
zwróci wszystkie prawidłowe wartości Color
Korzystanie classmethod
z __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)
lub jeśli masz wiele klas Enum i chcesz wyodrębnić metodę klasy:
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"