Enumeraciones
Las enumeraciones reemplazan cadenas y enteros "mágicos" con constantes con nombre y tipadas. Los miembros son singletons: estables en identidad y auto-documentados en APIs, configuraciones y sentencias match.
Receta
from enum import StrEnum, auto
class Status(StrEnum):
PENDING = "pending"
ACTIVE = "active"
CLOSED = "closed"
class Priority(StrEnum):
LOW = auto()
MEDIUM = auto()
HIGH = auto()Cuándo usar esto:
- Métodos HTTP, estados de pedidos, nombres de roles
- Valores de configuración validados contra un conjunto fijo
- Ramificación
matchexhaustiva - Permisos de máscara de bits con
Flag
Ejemplo de Trabajo
from enum import Flag, StrEnum, auto
class Status(StrEnum):
PENDING = "pending"
ACTIVE = "active"
CLOSED = "closed"
class Role(StrEnum):
ADMIN = "admin"
DEV = "dev"
VIEWER = "viewer"
class Permission(Flag):
READ = auto()
WRITE = auto()
EXECUTE = auto()
ADMIN_PERMS = Permission.READ | Permission.WRITE | Permission.EXECUTE
def authorize(role: Role, required: Role) -> bool:
hierarchy = {Role.VIEWER: 0, Role.DEV: 1, Role.ADMIN: 2}
return hierarchy[role] >= hierarchy[required]
def can_read(perms: Permission) -> bool:
return Permission.READ in perms
def describe_status(status: Status) -> str:
match status:
case Status.PENDING:
return "esperando"
case Status.ACTIVE:
return "en ejecución"
case Status.CLOSED:
return "terminado"
if __name__ == "__main__":
print(authorize(Role.ADMIN, Role.DEV))
print(can_read(ADMIN_PERMS))
print(describe_status(Status.ACTIVE))Lo que esto demuestra:
StrEnumse serializa a su valor de cadena para logs JSONFlagse combina con|y se prueba coninmatchsobre miembros de enumeración para un manejo exhaustivoauto()genera valores para enumeraciones que no son de cadena
Análisis Profundo
Cómo Funciona
- EnumMeta - Crea objetos miembro únicos en la definición de la clase.
- Valor vs identidad -
Status.ACTIVE is Status.ACTIVEsiempre es Verdadero. - StrEnum - Subclase de
stryEnum- compara igual a su valor de cadena. - IntEnum - Subclase de
int- úselo con precaución cuando necesite comportamiento deint. - API Funcional -
Enum('Color', ['RED', 'GREEN'])para enumeraciones dinámicas.
Variedades de Enumeración
| Clase | Tipo de miembro |
|---|---|
Enum | Genérico |
StrEnum | str |
IntEnum | int |
Flag | máscara de bits int |
Notas de Python
# Serialización JSON
status = Status.ACTIVE
payload = {"status": status} # StrEnum -> "active" en muchos codificadores
# obtener por valor
Status("active") # devuelve Status.ACTIVETrampas Comunes
- IntEnum isinstance int - Pasa a funciones que esperan
intpero puede confundir a los verificadores de tipos. Solución: PrefieraStrEnumoEnumsimple. - Comparar con cadenas sin procesar sin StrEnum -
Status.ACTIVE == "active"es Falso enEnumsimple. Solución:StrEnumo comparar.value. - Valores duplicados como alias - El segundo nombre es un alias del primer miembro. Solución: Use el decorador
@enum.unique. - Miembros de enumeración mutables - No se pueden asignar nuevos atributos a los miembros. Solución: Adjunte datos a través de
Enumcon valores de tupla(nombre, extra). - Miembros infinitos de Flag - Las banderas combinadas crean miembros compuestos. Solución: Documente los valores compuestos o use subconjuntos explícitos.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
Literal["a","b"] | Solo sugerencias de tipo | Necesita validación en tiempo de ejecución |
Cadenas de módulo const | Scripts pequeños | La estabilidad de la API importa |
Pydantic Literal | Validación HTTP | Enumeraciones de dominio interno |
| Tabla de búsqueda en base de datos | Valores dinámicos definidos por el usuario | Estados fijos del sistema |
Preguntas Frecuentes
¿Enum vs Literal?
Enum son objetos en tiempo de ejecución con identidad. Literal es solo para tipado estático de cadenas fijas.
¿StrEnum JSON?
A menudo se serializa como valor de cadena; verifique con su codificador JSON (la biblioteca json estándar usa el valor para StrEnum).
¿Cómo obtener todos los miembros?
list(Status) o Status.__members__.values().
¿Decorador unique?
@unique en la clase Enum genera un error si dos nombres se mapean al mismo valor sin querer.
¿Operadores de Flag?
| unión, & intersección, ~ invertir dentro de la definición de Flag.
¿enum en match?
Coincidencia exhaustiva: mypy/pyright advierten sobre casos faltantes con configuraciones estrictas.
¿extender Enum?
Se desaconseja la subclasificación de Enum excepto en casos especiales; componga en su lugar.
¿valores de auto()?
Enteros que se incrementan a partir de uno; anule si se necesitan valores estables entre versiones.
¿opciones de Django?
TextChoices/IntegerChoices son envoltorios de enumeración de Django; patrones similares.
¿almacenamiento en base de datos?
Almacene .value en la columna; reconstruya con Enum(value) al leer.
Relacionado
- Flujo de Control - match/case
- Conceptos Básicos de Type Hints - Tipos Literal
- Literal, Final y Annotated - constantes precisas
- dataclasses - campos de enumeración en registros
Versiones de la Pila: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+ y uv 0.6+.