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

    Estructura de código y XML para canonicalización con Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    ElementTree canonicalize: normaliza XML en Python

    Aprende ElementTree canonicalize en Python para comparar XML, generar hashes estables y controlar namespaces, espacios y comentarios.

    Ler mais

    Tempo de leitura: 5 minutos
    22/10/2026
    Código Python en una pantalla
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    T-strings y templatelib: interpolación estructurada

    Aprende t-strings y string.templatelib en Python para interpolación estructurada, renderizado seguro, logs y procesamiento personalizado.

    Ler mais

    Tempo de leitura: 6 minutos
    22/10/2026
    Base SQLite y código Python para exportación selectiva con iterdump
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    SQLite iterdump: crea dumps selectivos en Python

    Aprende sqlite3.Connection.iterdump con filtro para crear dumps SQLite selectivos, validar dependencias y restaurar con seguridad.

    Ler mais

    Tempo de leitura: 4 minutos
    21/10/2026
    Código y archivos que representan compresión de datos con Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Zstandard rápido en Python

    Aprende compression.zstd en Python para comprimir archivos y datos con velocidad, streaming, integridad y seguridad.

    Ler mais

    Tempo de leitura: 7 minutos
    21/10/2026
    Archivo de configuración y estructura de código para ConfigParser en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    ConfigParser: lee INI sin sección en Python

    Aprende ConfigParser sin sección en Python con validación, tipos, compatibilidad, capas de configuración y escritura segura.

    Ler mais

    Tempo de leitura: 5 minutos
    20/10/2026
    Datos binarios y memoria de ordenador representando memoryview en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    memoryview count e index: busca sin copiar

    Aprende memoryview count e index en Python para buscar valores en buffers sin copias y validar datos binarios con eficiencia.

    Ler mais

    Tempo de leitura: 5 minutos
    20/10/2026