StrEnum no Python: enums como strings

Publicado em: 04/09/2026
Tempo de leitura: 4 minutos
Desenvolvedor trabalhando com enums e código Python

StrEnum é uma classe da biblioteca padrão do Python criada para representar conjuntos fechados de valores textuais. Ela combina o comportamento de str com Enum, permitindo que cada membro funcione como uma string real sem abrir mão da organização, da legibilidade e da segurança proporcionadas por enumerações.

Esse recurso é especialmente útil em APIs, configurações, serialização JSON, comandos de terminal, validação de dados e integrações com bancos de dados. Em vez de espalhar strings mágicas pelo código, você centraliza valores válidos em uma única classe.

Por que usar StrEnum

Imagine uma aplicação que aceita os estados pending, running e done. Usar strings simples funciona no começo, mas qualquer erro de digitação pode passar despercebido. Com StrEnum, os valores válidos ficam explícitos e reutilizáveis.

from enum import StrEnum

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

Agora Status.RUNNING é ao mesmo tempo um membro de enumeração e uma string compatível com muitas APIs existentes.

Diferença entre Enum e StrEnum

Com Enum tradicional, um membro não é automaticamente uma string. Já com StrEnum, comparações e operações comuns de texto se tornam mais naturais.

from enum import Enum, StrEnum

class CorEnum(Enum):
    RED = "red"

class CorStr(StrEnum):
    RED = "red"

print(CorStr.RED == "red")  # True
print(CorEnum.RED == "red") # False

Essa diferença reduz conversões manuais com .value. Ainda assim, quando você precisa do valor bruto de forma explícita, membro.value continua disponível.

Valores automáticos com auto

StrEnum funciona com auto(). Por padrão, o nome do membro é convertido para letras minúsculas.

from enum import StrEnum, auto

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

print(Ambiente.PRODUCTION.value)  # production

Esse padrão é prático quando o valor textual deve seguir diretamente o nome do membro.

Uso em APIs

Em APIs REST, valores textuais aparecem em parâmetros, payloads e respostas. StrEnum ajuda a manter esses contratos consistentes.

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

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

Para mais contexto sobre contratos HTTP, veja o guia de API REST com Python.

Conversão a partir de strings

Você pode construir um membro usando o valor textual.

entrada = "running"
status = Status(entrada)
print(status is Status.RUNNING)

Se o texto não existir, Python lança ValueError. Em entradas externas, trate esse caso para produzir mensagens claras.

def ler_status(texto: str) -> Status:
    try:
        return Status(texto)
    except ValueError as erro:
        validos = ", ".join(item.value for item in Status)
        raise ValueError(f"status inválido; use: {validos}") from erro

Serialização JSON

Como os membros se comportam como strings, muitos serializadores JSON lidam com eles naturalmente.

import json

payload = {"status": Status.DONE}
print(json.dumps(payload))

Mesmo assim, teste o comportamento do framework usado no projeto. Algumas bibliotecas fazem verificações rígidas de tipo e podem exigir .value.

StrEnum em configurações

Valores de ambiente, níveis de log, estratégias de cache e modos de execução são bons candidatos.

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

Isso combina bem com variáveis de ambiente e arquivos de configuração. O artigo sobre variáveis de ambiente no Python mostra como organizar esse tipo de entrada.

Comparação e identidade

Comparar um membro com uma string pode ser conveniente, mas dentro da lógica de domínio prefira comparar membros da própria enumeração usando is ou igualdade entre membros. Isso deixa a intenção mais clara.

if status is Status.DONE:
    print("processamento concluído")

Na fronteira da aplicação, como ao receber JSON, converta a string para o enum o mais cedo possível.

Iteração e listagem

Enumerar opções válidas é simples.

for status in Status:
    print(status.name, status.value)

Esse recurso ajuda a gerar escolhas de CLI, documentação e mensagens de validação.

Uso com match

O pattern matching do Python torna o código legível.

def descrever(status: Status) -> str:
    match status:
        case Status.PENDING:
            return "aguardando"
        case Status.RUNNING:
            return "em execução"
        case Status.DONE:
            return "concluído"

Veja também o tutorial sobre match case no Python.

Validação com type hints

Anotar parâmetros com StrEnum ajuda ferramentas estáticas e leitores do código.

def iniciar(ambiente: Ambiente) -> None:
    print(f"iniciando em {ambiente}")

Para aprofundar esse tema, consulte type hints no Python.

Aliases e valores duplicados

Se dois nomes recebem o mesmo valor, o segundo normalmente vira um alias. Isso pode ser útil em migrações, mas também pode esconder duplicidades.

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

Use aliases de forma deliberada e documentada. Em contratos externos, mudanças silenciosas podem confundir consumidores.

Customizando valores ausentes

É possível implementar _missing_ para aceitar variações controladas.

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

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

Assim, entradas como " YES " podem ser normalizadas sem duplicar lógica fora da classe.

Cuidados com compatibilidade

StrEnum foi incorporado à biblioteca padrão em versões modernas do Python. Se o projeto suporta versões antigas, você pode usar uma combinação de str e Enum ou uma biblioteca de compatibilidade.

from enum import Enum

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

O comportamento é semelhante, mas detalhes como representação textual podem variar. Teste integrações e serialização.

Boas práticas

Use StrEnum para conjuntos pequenos e fechados. Converta strings externas para membros na entrada da aplicação. Evite usar enumerações para valores que mudam frequentemente ou vêm de banco de dados. Prefira nomes claros, valores estáveis e documentação de qualquer alias.

Também vale escrever testes para conversão, serialização, valores inválidos e compatibilidade com frameworks. O conteúdo sobre pytest no Python pode ajudar.

Referências

Consulte a documentação oficial de StrEnum e a PEP 663 para entender decisões sobre representação e comportamento de enums baseados em strings.

Conclusão

StrEnum oferece uma forma moderna de modelar valores textuais controlados. Ele reduz strings mágicas, melhora validação, facilita serialização e torna contratos de domínio mais claros. Quando usado nas fronteiras certas, ajuda a manter aplicações Python previsíveis sem exigir conversões repetitivas ou estruturas complexas.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Pastas e diretórios para contextlib.chdir no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    contextlib.chdir: restaure o diretório automaticamente

    Aprenda contextlib.chdir no Python para trocar diretórios temporariamente com segurança, testes confiáveis e restauração automática do caminho.

    Ler mais

    Tempo de leitura: 5 minutos
    03/09/2026
    Monitoramento de desempenho e execução de código Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    sys.monitoring: instrumentação de baixo overhead

    Aprenda sys.monitoring no Python para instrumentar execução com baixo overhead, eventos, callbacks, ferramentas e observabilidade segura.

    Ler mais

    Tempo de leitura: 6 minutos
    03/09/2026
    Desenvolvedor organizando dados com operator.attrgetter no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    operator.attrgetter: ordene objetos por atributos

    Aprenda operator.attrgetter no Python para ordenar, agrupar e transformar objetos por atributos simples ou aninhados com código mais claro.

    Ler mais

    Tempo de leitura: 5 minutos
    02/09/2026
    Programação assíncrona com asyncio.Runner no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    asyncio.Runner: reutilize o event loop com segurança

    Aprenda asyncio.Runner no Python para reutilizar o event loop, controlar contexto, sinais, debug e encerramento assíncrono com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    02/09/2026
    Compressão de dados binários com Zstandard no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Zstandard com streams e dicionários

    Aprenda compression.zstd no Python para compactar dados com Zstandard, usar streaming, dicionários e limites seguros.

    Ler mais

    Tempo de leitura: 7 minutos
    01/09/2026
    Aplicação Python empacotada como arquivo executável com zipapp
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    zipapp no Python: crie apps executáveis

    Aprenda zipapp no Python para empacotar aplicações em um arquivo pyz executável, portátil e simples de distribuir.

    Ler mais

    Tempo de leitura: 6 minutos
    01/09/2026