Resumo : neste tutorial, você aprenderá sobre aliases de membros de enumeração e como usar o decorador exclusivo enum para garantir a exclusividade dos valores dos membros.
Introdução aos aliases enum
Por definição, os valores dos membros de enumeração são exclusivos. No entanto, você pode criar nomes de membros diferentes com os mesmos valores.
Por exemplo, o seguinte define a Color
enumeração:
from enum import Enum
class Color(Enum):
RED = 1
CRIMSON = 1
SALMON = 1
GREEN = 2
BLUE = 3
Linguagem de código: Python ( python )
Neste exemplo, a Color
enumeração tem os membros RED
, CRIMSON
e SALMON
com o mesmo valor 1.
Quando você define vários membros em uma enumeração com os mesmos valores, o Python não cria membros diferentes, mas aliases.
Neste exemplo, the RED
é o membro principal, enquanto os membros CRIMSON
e SALMON
são os apelidos do RED
membro
As declarações a seguir retornam True
porque CRIMSON
e SALMON
os membros são membros do RED:
print(Color.RED is Color.CRIMSON)
print(Color.RED is Color.SALMON)
Linguagem de código: Python ( python )
Saída:
True
True
Linguagem de código: Python ( python )
Ao procurar um membro por valor, você sempre obterá o membro principal, não os aliases. Por exemplo, a instrução a seguir retorna o RED
membro:
print(Color(1))
Linguagem de código: Python ( python )
Saída:
Color.RED
Linguagem de código: Python ( python )
Ao iterar os membros de uma enumeração com aliases, você obterá apenas os membros principais, não os aliases. Por exemplo:
for color in Color:
print(color)
Linguagem de código: Python ( python )
Ele retorna apenas três membros:
Color.RED
Color.GREEN
Color.BLUE
Linguagem de código: Python ( python )
Para obter todos os membros incluindo aliases, você precisa usar a __member__
propriedade da classe de enumeração. Por exemplo:
from enum import Enum
from pprint import pprint
class Color(Enum):
RED = 1
CRIMSON = 1
SALMON = 1
GREEN = 2
BLUE = 3
pprint(Color.__members__)
Linguagem de código: Python ( python )
Saída:
mappingproxy({'BLUE': <Color.BLUE: 3>,
'CRIMSON': <Color.RED: 1>,
'GREEN': <Color.GREEN: 2>,
'RED': <Color.RED: 1>,
'SALMON': <Color.RED: 1>})
Linguagem de código: Python ( python )
Conforme mostrado claramente na saída, e CRIMSON
fazem SALMON
referência ao mesmo objeto que é referenciado pelo RED
membro:
<Color.RED: 1>
Linguagem de código: Python ( python )
Quando usar aliases enum
Os aliases de enumeração podem ser úteis em algumas situações. Por exemplo, suponha que você precise lidar com APIs de dois sistemas diferentes. E cada sistema tem um status de resposta diferente com o mesmo significado mostrado na tabela a seguir:
Sistema 1 | Sistema 2 | Significado |
---|---|---|
SOLICITANDO | PENDENTE | A solicitação está em andamento |
OK | REALIZADA | A solicitação foi concluída com sucesso |
NÃO ESTÁ TUDO BEM | REJEITADO | A solicitação falhou |
Para padronizar os códigos de status desses sistemas, você pode usar aliases de enumeração da seguinte maneira:
Seu sistema | Sistema 1 | Sistema 2 | Significado |
---|---|---|---|
EM ANDAMENTO | SOLICITANDO | PENDENTE | A solicitação está em andamento |
SUCESSO | OK | REALIZADA | A solicitação foi concluída com sucesso |
ERRO | NÃO ESTÁ TUDO BEM | REJEITADO | A solicitação falhou |
O seguinte define a ResponseStatus
enumeração com aliases:
from enum import Enum
class ResponseStatus(Enum):
# in progress
IN_PROGRESS = 1
REQUESTING = 1
PENDING = 1
# success
SUCCESS = 2
OK = 2
FULFILLED = 2
# error
ERROR = 3
NOT_OK = 3
REJECTED = 3
Linguagem de código: Python ( python )
A seguir, comparamos o código de resposta do sistema 1 para verificar se a solicitação foi bem-sucedida ou não:
code = 'OK'
if ResponseStatus[code] is ResponseStatus.SUCCESS:
print('The request completed successfully')
Linguagem de código: Python ( python )
Saída:
The request completed successfully
Linguagem de código: Python ( python )
Da mesma forma, você pode verificar o código de resposta do sistema 2 para ver se a solicitação foi bem-sucedida:
code = 'FULFILLED'
if ResponseStatus[code] is ResponseStatus.SUCCESS:
print('The request completed successfully')
Linguagem de código: Python ( python )
Saída:
print('The request completed successfully')
Linguagem de código: Python ( python )
@enum.decorador exclusivo
Para definir uma enumeração sem aliases, você pode usar cuidadosamente valores exclusivos para os membros. Por exemplo:
from enum import Enum
class Day(Enum):
MON = 'Monday'
TUE = 'Tuesday'
WED = 'Wednesday'
THU = 'Thursday'
FRI = 'Friday'
SAT = 'Saturday'
SUN = 'Sunday'
Linguagem de código: Python ( python )
Mas você pode acidentalmente usar os mesmos valores para dois membros assim:
class Day(Enum):
MON = 'Monday'
TUE = 'Monday'
WED = 'Wednesday'
THU = 'Thursday'
FRI = 'Friday'
SAT = 'Saturday'
SUN = 'Sunday'
Linguagem de código: Python ( python )
Neste exemplo, o TUE
membro é o alias do MON
membro, o que você pode não esperar.
Para garantir que uma enumeração não tenha alias, você pode usar o @enum.unique
decorador do enum
módulo.
Quando você decora uma enumeração com o @enum.unique
decorador, o Python lançará uma exceção se a enumeração tiver aliases.
Por exemplo, o seguinte irá gerar um ValueError
:
import enum
from enum import Enum
@enum.unique
class Day(Enum):
MON = 'Monday'
TUE = 'Monday'
WED = 'Wednesday'
THU = 'Thursday'
FRI = 'Friday'
SAT = 'Saturday'
SUN = 'Sunday'
Linguagem de código: Python ( python )
Erro:
ValueError: duplicate values found in <enum 'Day'>: TUE -> MON
Linguagem de código: Python ( python )
Resumo
- Quando uma enumeração possui membros diferentes com os mesmos valores, o primeiro membro é o membro principal, enquanto os outros são apelidos do membro principal.
- Use o
@enum.unique
decorador doenum
módulo para impor a exclusividade dos valores dos membros.