StrEnum en Python: enums como strings

Publicado el: 04/09/2026
Tempo de leitura: 5 minutos
Desarrollador trabajando con enums y código Python

StrEnum es una clase de la biblioteca estándar de Python diseñada para representar conjuntos cerrados de valores textuales. Combina el comportamiento de str con Enum, por lo que cada miembro funciona como una cadena real y, al mismo tiempo, conserva la organización, validación y claridad de una enumeración.

Este recurso es útil en APIs, configuraciones, serialización JSON, herramientas de línea de comandos, estados de aplicaciones e integraciones con bases de datos. En lugar de repetir cadenas mágicas por todo el proyecto, puedes definir los valores válidos una sola vez.

Por qué usar StrEnum

Imagina una aplicación que acepta los estados pending, running y done. Las cadenas simples funcionan al principio, pero cualquier error tipográfico puede generar comportamientos inconsistentes. Con StrEnum, el contrato queda explícito.

from enum import StrEnum

class Estado(StrEnum):
    PENDING = "pending"
    RUNNING = "running"
    DONE = "done"

Estado.RUNNING es ahora un miembro de enumeración y también un valor compatible con cadenas.

Diferencia entre Enum y StrEnum

Un miembro de Enum tradicional no es automáticamente igual a su cadena subyacente. Un miembro de StrEnum sí lo es.

from enum import Enum, StrEnum

class ColorEnum(Enum):
    RED = "red"

class ColorStr(StrEnum):
    RED = "red"

print(ColorStr.RED == "red")  # True
print(ColorEnum.RED == "red") # False

Esto reduce conversiones repetitivas con .value, aunque el valor bruto sigue disponible cuando deseas ser explícito.

Valores automáticos

StrEnum funciona con auto(). De forma predeterminada, el nombre del miembro se convierte en minúsculas.

from enum import StrEnum, auto

class Entorno(StrEnum):
    DEVELOPMENT = auto()
    STAGING = auto()
    PRODUCTION = auto()

print(Entorno.PRODUCTION.value)  # production

Este patrón es práctico cuando el valor público debe seguir directamente el nombre del miembro.

Uso en APIs

Las APIs REST intercambian texto en parámetros, solicitudes y respuestas. Una enumeración de strings mantiene esos valores estables y fáciles de documentar.

class Formato(StrEnum):
    JSON = "json"
    CSV = "csv"
    XML = "xml"

def exportar(formato: Formato):
    if formato is Formato.JSON:
        return {"items": []}
    if formato is Formato.CSV:
        return "items\n"
    return ""

Para ampliar este tema, consulta la guía sobre API REST con Python.

Conversión desde cadenas externas

Puedes construir un miembro utilizando su valor textual.

entrada = "running"
estado = Estado(entrada)
print(estado is Estado.RUNNING)

Si el valor no existe, Python lanza ValueError. En los límites de la aplicación conviene capturar el error y devolver un mensaje útil.

def leer_estado(texto: str) -> Estado:
    try:
        return Estado(texto)
    except ValueError as error:
        opciones = ", ".join(item.value for item in Estado)
        raise ValueError(f"estado inválido; usa: {opciones}") from error

Serialización JSON

Como los miembros se comportan como strings, muchos codificadores JSON los serializan de forma natural.

import json

payload = {"estado": Estado.DONE}
print(json.dumps(payload))

Sin embargo, algunos frameworks hacen verificaciones estrictas y pueden exigir .value. Añade pruebas de integración para confirmar el comportamiento real.

Configuraciones y variables de entorno

Entornos, niveles de log, estrategias de caché y modos de ejecución son buenos candidatos para StrEnum.

class NivelLog(StrEnum):
    DEBUG = "debug"
    INFO = "info"
    WARNING = "warning"
    ERROR = "error"

Este enfoque combina bien con archivos de configuración y variables de entorno. Lee también el artículo sobre variables de entorno en Python.

Identidad e igualdad

Comparar un miembro con una cadena puede ser cómodo, pero dentro de la lógica de dominio suele ser más claro comparar miembros de la propia enumeración.

if estado is Estado.DONE:
    print("proceso finalizado")

Convierte las cadenas externas al entrar en la aplicación y conserva el tipo fuerte internamente.

Iteración y opciones válidas

Las enumeraciones son iterables, lo que facilita generar documentación, opciones de CLI y mensajes de validación.

for estado in Estado:
    print(estado.name, estado.value)

Así evitas mantener una segunda lista separada de valores permitidos.

Pattern matching

El pattern matching de Python funciona de forma clara con miembros de enum.

def describir(estado: Estado) -> str:
    match estado:
        case Estado.PENDING:
            return "en espera"
        case Estado.RUNNING:
            return "en ejecución"
        case Estado.DONE:
            return "finalizado"

Consulta el tutorial de match case en Python para más ejemplos.

Type hints

Anotar parámetros con StrEnum ayuda a los analizadores estáticos y documenta mejor las interfaces.

def iniciar(entorno: Entorno) -> None:
    print(f"iniciando en {entorno}")

La guía sobre type hints en Python explica cómo aprovechar estas anotaciones.

Aliases y valores duplicados

Si dos nombres reciben el mismo valor, el segundo suele convertirse en alias.

class Metodo(StrEnum):
    GET = "get"
    READ = "get"

Los aliases pueden ayudar en migraciones, pero también pueden ocultar errores. Úsalos de forma intencional y documenta cuál es el nombre principal.

Personalizar valores ausentes

Puedes implementar _missing_ para normalizar variantes controladas.

class Respuesta(StrEnum):
    YES = "yes"
    NO = "no"

    @classmethod
    def _missing_(cls, value):
        if isinstance(value, str):
            normalizado = value.strip().lower()
            for item in cls:
                if item.value == normalizado:
                    return item
        return None

De esta manera, valores como " YES " pueden aceptarse sin repetir la lógica de normalización en muchos lugares.

Integración con bases de datos

Las enumeraciones de strings son cómodas para columnas de base de datos porque los valores almacenados siguen siendo legibles. Sin embargo, debes decidir si la restricción pertenece a la aplicación o a la base de datos.

Si los valores cambian con frecuencia o son administrados por usuarios, una tabla de referencia puede ser mejor que una enumeración definida en código.

Compatibilidad con versiones anteriores

StrEnum forma parte de versiones modernas de Python. Si el proyecto soporta intérpretes antiguos, puedes combinar str y Enum.

from enum import Enum

class EstadoCompat(str, Enum):
    PENDING = "pending"
    RUNNING = "running"

El comportamiento es parecido, pero la representación y la integración con frameworks pueden variar. Prueba las versiones que realmente soportas.

Pruebas recomendadas

Prueba conversiones válidas, valores inválidos, serialización, aliases, normalización y compatibilidad con frameworks web. La guía de pytest en Python muestra patrones útiles para pruebas parametrizadas.

Cuándo no usarlo

StrEnum no es ideal para valores dinámicos que cambian con frecuencia, dependen de usuarios o llegan desde una tabla administrable. Las enumeraciones requieren cambios de código y despliegues. Úsalas para vocabularios estables y cerrados.

Buenas prácticas

Convierte el texto externo en la frontera, conserva miembros de enum dentro del dominio, utiliza valores estables en minúsculas, evita aliases accidentales, documenta deprecaciones y prueba la serialización. Prefiere varias enumeraciones pequeñas y específicas antes que una clase gigante con conceptos no relacionados.

Referencias

Consulta la documentación oficial de StrEnum y la PEP 663 para comprender las decisiones de representación y comportamiento.

Conclusión

StrEnum es una herramienta práctica para modelar valores textuales controlados. Reduce strings mágicas, mejora la validación, funciona bien con JSON y APIs y ofrece contratos más claros para herramientas estáticas. Usado en dominios estables, hace que las aplicaciones Python sean más predecibles sin añadir complejidad innecesaria.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Carpetas y directorios para contextlib.chdir en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    contextlib.chdir: restaura directorios automáticamente

    Aprende contextlib.chdir en Python para cambiar directorios temporalmente, restaurar rutas y crear pruebas confiables sin errores de estado global.

    Ler mais

    Tempo de leitura: 6 minutos
    03/09/2026
    Monitoreo de rendimiento y ejecución de código Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    sys.monitoring: instrumentación de bajo overhead

    Aprende sys.monitoring en Python para instrumentar ejecución con bajo overhead, eventos selectivos, callbacks y observabilidad segura.

    Ler mais

    Tempo de leitura: 6 minutos
    03/09/2026
    Desarrollador organizando datos con operator.attrgetter en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    operator.attrgetter: ordena objetos por atributos

    Aprende operator.attrgetter en Python para ordenar, agrupar y transformar objetos por atributos simples o anidados con código claro.

    Ler mais

    Tempo de leitura: 4 minutos
    02/09/2026
    Programación asíncrona con asyncio.Runner en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    asyncio.Runner: reutiliza el event loop con seguridad

    Aprende asyncio.Runner en Python para reutilizar el event loop, controlar contexto, señales, debug, cancelación y cierre asíncrono seguro.

    Ler mais

    Tempo de leitura: 7 minutos
    02/09/2026
    Compresión de datos binarios con Zstandard en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Zstandard con streams y diccionarios

    Aprende compression.zstd en Python para comprimir datos con Zstandard, streaming, diccionarios y límites seguros.

    Ler mais

    Tempo de leitura: 7 minutos
    01/09/2026
    Aplicación Python empaquetada como archivo ejecutable con zipapp
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    zipapp en Python: crea apps ejecutables

    Aprende zipapp en Python para empaquetar aplicaciones como archivos pyz ejecutables, incluir dependencias y distribuirlas con seguridad.

    Ler mais

    Tempo de leitura: 5 minutos
    01/09/2026