keyword no Python: palavras reservadas

Publicado em: 07/08/2026
Tempo de leitura: 7 minutos
Código-fonte representando palavras reservadas e soft keywords no Python

Geradores de código, validadores de formulários, ferramentas de refatoração e sistemas que transformam nomes externos em identificadores Python precisam saber se uma palavra pode ser usada como variável, atributo, função ou classe. O módulo keyword no Python expõe as palavras reservadas reconhecidas pelo interpretador atual e também as chamadas soft keywords, que possuem significado especial somente em contextos específicos.

Neste guia, você aprenderá a usar iskeyword(), kwlist, issoftkeyword() e softkwlist, além de criar validadores compatíveis com várias versões. O conteúdo complementa nossos artigos sobre tokenize, symtable, codeop, AST no Python e types.

O que é uma palavra reservada

Palavras reservadas participam da gramática da linguagem e não podem ser usadas como identificadores comuns.

class = "relatorio"  # SyntaxError
return = 10          # SyntaxError

Exemplos conhecidos incluem class, def, return, if, for, while, try, import e lambda. A lista depende da versão do Python e não deve ser copiada manualmente para uma ferramenta duradoura.

Verificar com iskeyword()

keyword.iskeyword() informa se uma string é uma palavra reservada do interpretador atual.

import keyword

print(keyword.iskeyword("class"))   # True
print(keyword.iskeyword("cliente")) # False

A função aceita uma string e devolve booleano. Ela não verifica todas as regras de identificadores; apenas palavras reservadas.

Consultar kwlist

keyword.kwlist contém as palavras reservadas em ordem alfabética.

import keyword

for palavra in keyword.kwlist:
    print(palavra)

A lista é útil para interfaces educativas, syntax highlighting, testes e geração de nomes alternativos.

Não altere kwlist

Embora o objeto exposto seja uma lista, modificá-lo não muda a gramática do Python e pode quebrar o próprio código que consulta o módulo.

# Não faça isso
keyword.kwlist.append("cliente")

Trate a lista como informação somente leitura. Faça uma cópia ou converta para frozenset quando precisar de uma coleção própria.

RESERVADAS = frozenset(keyword.kwlist)

O que são soft keywords

Soft keywords são palavras que recebem significado especial apenas em determinados contextos gramaticais. Fora desses contextos, ainda podem funcionar como identificadores.

Esse mecanismo permite evoluir a linguagem com menos quebra de código existente. Em versões modernas, estruturas como pattern matching e declarações de tipos utilizam palavras contextuais.

Verificar soft keywords

keyword.issoftkeyword() verifica se uma string pertence à lista contextual do interpretador.

print(keyword.issoftkeyword("match"))
print(keyword.issoftkeyword("case"))
print(keyword.issoftkeyword("cliente"))

A documentação oficial de keyword recomenda consultar o módulo em vez de manter listas fixas, pois a gramática pode evoluir.

Consultar softkwlist

for palavra in keyword.softkwlist:
    print(palavra)

Nem toda soft keyword precisa ser rejeitada como nome. A decisão depende de onde o identificador será inserido.

Soft keyword pode ser identificador

Uma palavra contextual pode ser válida em várias posições.

match = "texto"
case = 10
print(match, case)

Porém, em uma construção de pattern matching, as mesmas palavras participam da sintaxe.

match valor:
    case 0:
        print("zero")

Uma ferramenta de geração de código deve considerar o contexto completo, não apenas bloquear todas as soft keywords.

Validar um identificador completo

Para verificar se uma string pode ser um identificador simples, combine str.isidentifier() com iskeyword().

def identificador_valido(nome: str) -> bool:
    return nome.isidentifier() and not keyword.iskeyword(nome)

print(identificador_valido("cliente_id"))
print(identificador_valido("2clientes"))
print(identificador_valido("class"))

isidentifier() considera regras Unicode da versão atual. Ele não informa se o nome é apropriado, legível ou permitido pela política do projeto.

Nomes Unicode

Python aceita muitos caracteres Unicode em identificadores.

print("ação".isidentifier())
print("π".isidentifier())

A referência oficial de análise lexical descreve normalização e categorias permitidas. Em APIs públicas, nomes ASCII podem ser preferíveis por interoperabilidade, mas isso é uma política do projeto, não uma exigência da linguagem.

Gerar um nome seguro

Uma ferramenta pode normalizar um nome externo e acrescentar sufixo quando ele coincide com uma keyword.

import re
import unicodedata


def criar_identificador(texto: str) -> str:
    texto = unicodedata.normalize("NFKC", texto).strip()
    texto = re.sub(r"\W+", "_", texto, flags=re.UNICODE)
    texto = texto.strip("_") or "valor"

    if texto[0].isdigit():
        texto = "_" + texto

    if keyword.iskeyword(texto):
        texto += "_"

    if not texto.isidentifier():
        raise ValueError("não foi possível criar identificador")

    return texto

Não use essa transformação para decisões de segurança ou autorização. Nomes visualmente parecidos podem usar caracteres Unicode diferentes.

Convenção do underscore

Acrescentar underscore é uma convenção comum para escapar de palavras reservadas.

class_ = "Relatorio"
from_ = "origem"
async_ = False

Evite abreviações obscuras. Quando o nome vem de um campo externo, mantenha um mapa entre o nome original e o identificador Python.

Validar nomes de atributos

Palavras reservadas podem ser usadas como chaves de dicionário e, com APIs dinâmicas, até como nomes de atributos armazenados.

objeto.__dict__["class"] = "especial"
print(getattr(objeto, "class"))

Entretanto, objeto.class não é sintaxe válida. Geradores de código devem rejeitar ou transformar esses nomes mesmo quando setattr() os aceita.

Campos de JSON e banco de dados

Dados externos frequentemente possuem campos como class, from ou global. Não altere o esquema externo silenciosamente.

MAPA = {
    "class": "class_",
    "from": "from_",
}

valor = payload["class"]
modelo.class_ = valor

Serialização de volta deve restaurar o nome original.

Geração de funções

Antes de inserir parâmetros em código-fonte gerado, valide cada nome.

def assinatura_segura(nomes):
    for nome in nomes:
        if not identificador_valido(nome):
            raise ValueError(f"parâmetro inválido: {nome!r}")
    return ", ".join(nomes)

Mesmo com nomes válidos, concatenar código e executar exec() continua perigoso quando outras partes vêm de usuários. Prefira estruturas de dados, closures ou AST construído com regras restritas.

Keywords em templates

Um template que gera classes, dataclasses ou APIs deve testar nomes de classe, atributos, parâmetros e métodos separadamente.

O fato de um nome ser válido como atributo via getattr() não garante que possa aparecer após ponto em código. Compile uma amostra em testes para detectar regras contextuais.

Compatibilidade entre versões

Uma palavra pode tornar-se reservada ou contextual em uma versão futura. Ferramentas que geram código destinado a outro runtime não devem consultar apenas o Python em que estão rodando.

Opções possíveis:

  • executar a validação no interpretador de destino;
  • manter tabelas versionadas obtidas de fontes oficiais;
  • compilar o código com todas as versões suportadas;
  • usar containers ou CI com uma matriz de Python.

Não reutilizar lista de uma versão

Salvar keyword.kwlist de um Python antigo e aplicá-la para sempre pode permitir sintaxe inválida em versões novas ou rejeitar nomes que deixaram de ser especiais.

Registre a versão do interpretador junto aos artefatos gerados e teste a versão mínima e máxima suportadas.

Syntax highlighting

Editores podem usar kwlist para palavras rígidas e softkwlist para realce contextual. Apenas colorir todas as soft keywords como reservadas em qualquer posição gera falsos positivos.

Um highlighter preciso precisa de tokenizer ou parser. O módulo keyword fornece a classificação, não a posição gramatical.

Integração com tokenize

tokenize normalmente classifica identificadores e keywords como tokens NAME. A distinção final depende do parser.

import io
import tokenize

codigo = b"if valor: pass\n"
for token in tokenize.tokenize(io.BytesIO(codigo).readline):
    if token.type == tokenize.NAME:
        print(token.string, keyword.iskeyword(token.string))

Isso é útil em analisadores leves, mas soft keywords exigem contexto adicional.

Integração com AST

O parser já aplica as regras da versão atual. Compilar ou usar ast.parse() é a confirmação mais forte de que um trecho completo possui sintaxe válida.

import ast

try:
    ast.parse("cliente = 1")
except SyntaxError as erro:
    print(erro)

Não execute o código para validá-lo; parsing é suficiente para sintaxe.

Ferramentas de refatoração

Ao renomear símbolos, verifique:

  • se o novo nome é identificador;
  • se não é keyword rígida;
  • se não cria conflito no escopo;
  • se soft keywords são válidas naquele contexto;
  • se referências em strings e configurações também precisam mudar.

symtable e AST ajudam a analisar escopos e usos.

Validação em APIs

Se uma API recebe o nome de um campo que será convertido em atributo Python, retorne uma mensagem clara.

def validar_campo(nome):
    if not nome.isidentifier():
        raise ValueError("o campo não é um identificador Python")
    if keyword.iskeyword(nome):
        raise ValueError(f"{nome!r} é palavra reservada")

Você pode oferecer automaticamente uma alternativa, mas mostre o mapeamento ao usuário.

Desempenho

Consultas são rápidas, mas uma ferramenta que valida milhões de nomes pode converter as listas em conjuntos próprios.

KEYWORDS = frozenset(keyword.kwlist)
SOFT_KEYWORDS = frozenset(keyword.softkwlist)

Não modifique as coleções globais do módulo e reconstrua os conjuntos quando mudar de interpretador.

Testes

def test_identificadores():
    assert identificador_valido("cliente")
    assert identificador_valido("ação")
    assert not identificador_valido("class")
    assert not identificador_valido("2clientes")
    assert not identificador_valido("cliente-id")

Inclua todas as keywords atuais, soft keywords em diferentes contextos, Unicode, strings vazias e nomes próximos a built-ins como list e str.

Built-ins não são keywords

Nomes como list, dict, str, id e input não são reservados.

print(keyword.iskeyword("list"))  # False

Atribuir a esses nomes é permitido, mas pode esconder built-ins e confundir o código.

list = [1, 2, 3]
# list("abc") agora falha

Linters ajudam a aplicar essa política adicional.

Erros frequentes

  • Validar apenas com iskeyword().
  • Bloquear toda soft keyword em qualquer contexto.
  • Manter uma lista manual desatualizada.
  • Presumir que setattr() garante sintaxe com ponto.
  • Confundir built-ins com palavras reservadas.
  • Gerar código para outra versão sem testar.
  • Modificar kwlist ou softkwlist.
  • Executar código apenas para validar sintaxe.

Boas práticas

  • Combine isidentifier() e iskeyword().
  • Considere soft keywords conforme o contexto.
  • Consulte a versão real do interpretador alvo.
  • Mantenha mapas para nomes externos transformados.
  • Use AST ou compilação para validar trechos completos.
  • Teste todas as versões suportadas.
  • Aplique lint para built-ins sobrescritos.
  • Trate Unicode e normalização conscientemente.

Conclusão

O módulo keyword no Python fornece a lista oficial de palavras reservadas e palavras-chave contextuais do interpretador atual. iskeyword() e issoftkeyword() ajudam validadores, geradores de código, editores e refatoradores a acompanhar a evolução da linguagem.

A validação correta vai além de uma lista: nomes precisam satisfazer isidentifier(), soft keywords dependem do contexto e código destinado a outra versão precisa ser testado naquele runtime. Com essas camadas, ferramentas podem produzir identificadores legíveis sem gerar sintaxe inválida.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código assíncrono representando asyncio.eager_task_factory no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    asyncio.eager_task_factory: reduza overhead de tarefas

    Aprenda asyncio.eager_task_factory no Python para reduzir overhead, entender mudanças de ordem e otimizar corrotinas curtas com segurança.

    Ler mais

    Tempo de leitura: 4 minutos
    14/09/2026
    Desenvolvedor trabalhando com timestamps UTC e calendar.timegm no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    calendar.timegm: converta UTC para timestamp Unix

    Aprenda calendar.timegm no Python para converter datas UTC em timestamps Unix com segurança, testes e integração com datetime.

    Ler mais

    Tempo de leitura: 6 minutos
    14/09/2026
    Programador analisando código para identificar tipos MIME de arquivos no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    mimetypes.guess_file_type: detecte tipos MIME

    Aprenda mimetypes.guess_file_type no Python para detectar tipos MIME em caminhos, URLs, uploads e respostas HTTP com fallbacks seguros.

    Ler mais

    Tempo de leitura: 6 minutos
    13/09/2026
    Componentes de servidor representando interpretadores Python executando em paralelo
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    InterpreterPoolExecutor: paralelismo real no Python

    Aprenda InterpreterPoolExecutor no Python para executar tarefas CPU-bound em interpretadores isolados com paralelismo real.

    Ler mais

    Tempo de leitura: 6 minutos
    13/09/2026
    Microprocessador representando CPUs disponíveis para um processo Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    os.process_cpu_count: conte CPUs disponíveis

    Aprenda os.process_cpu_count no Python para dimensionar workers conforme as CPUs realmente disponíveis ao processo.

    Ler mais

    Tempo de leitura: 4 minutos
    12/09/2026
    Laptop com código digital representando dados BLOB no SQLite
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    sqlite3.Blob: leia BLOBs sem carregar tudo na memória

    Aprenda sqlite3.Blob no Python para ler e gravar BLOBs em partes, reduzir memória e trabalhar com dados binários no SQLite.

    Ler mais

    Tempo de leitura: 5 minutos
    12/09/2026