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

    Arquitetura de software representando classes abstratas com abc no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    abc no Python: classes abstratas

    Aprenda abc no Python para criar classes abstratas, métodos obrigatórios, subclasses virtuais e contratos de runtime.

    Ler mais

    Tempo de leitura: 6 minutos
    06/08/2026
    Código e estruturas representando tipos do runtime com o módulo types no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    types no Python: tipos do runtime

    Aprenda types no Python para usar SimpleNamespace, MappingProxyType, tipos do runtime e criação dinâmica de classes.

    Ler mais

    Tempo de leitura: 6 minutos
    06/08/2026
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    sched no Python: agende eventos

    Aprenda sched no Python para agendar eventos, controlar prioridades, cancelar tarefas e criar repetições com relógio monotônico.

    Ler mais

    Tempo de leitura: 8 minutos
    05/08/2026
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    atexit no Python: execute limpeza ao sair

    Aprenda atexit no Python para executar limpeza no encerramento, controlar ordem LIFO e evitar problemas com threads, sinais e exceções.

    Ler mais

    Tempo de leitura: 7 minutos
    05/08/2026
    Monitor com código binário representando análise de opcodes pickle com pickletools no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pickletools no Python: analise pickles

    Aprenda pickletools no Python para desmontar pickles, analisar opcodes e otimizar fluxos sem executar dados não confiáveis.

    Ler mais

    Tempo de leitura: 7 minutos
    05/08/2026
    Código-fonte em tela representando análise com tokenize no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    tokenize no Python: analise código-fonte

    Aprenda tokenize no Python para ler tokens, comentários, indentação, codificação, posições e reconstruir código-fonte com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    05/08/2026