tokenize en Python: lee tokens del código

Publicado el: 27/08/2026
Tempo de leitura: 6 minutos
Gold Bitcoin coins displayed on a sparkling gold texture, representing digital currency and finance.

El módulo tokenize convierte código fuente Python en una secuencia de tokens léxicos. Cada token describe un fragmento como nombre, número, string, operador, comentario, indentación, salto de línea o marcador final. Esta capa es útil en formatters, linters, converters, herramientas de documentación, análisis de comentarios y transformaciones que deben conservar más detalle textual que una AST.

Los tokens no representan todo el significado del programa. No resuelven scopes, imports, tipos ni comportamiento en runtime. Usa ast para estructura, symtable para símbolos y dis para bytecode. Elige tokenize cuando importen whitespace, comentarios, posiciones y grafía literal.

Tokeniza bytes

tokenize.tokenize() recibe una función readline que devuelve bytes.

from io import BytesIO
from tokenize import tokenize

codigo = b"x = 10 + 2\n"
for item in tokenize(BytesIO(codigo).readline):
    print(item)

La secuencia incluye un token ENCODING, los tokens del fuente y ENDMARKER.

TokenInfo

Cada resultado es un TokenInfo con campos type, string, start, end y line.

for item in tokenize(BytesIO(codigo).readline):
    print(item.type, item.string, item.start, item.end)

start y end son pares línea-columna. line contiene la línea física original.

Nombres legibles

Los tipos son enteros definidos por token. Usa token.tok_name.

import token

nombre = token.tok_name[item.type]

No persistas IDs numéricos crudos como formato estable.

exact_type para operadores

Operadores y delimitadores suelen usar el tipo general OP. TokenInfo.exact_type identifica el símbolo exacto.

import token

if item.type == token.OP:
    print(token.tok_name[item.exact_type])

Así distingues +, +=, paréntesis, dos puntos y otros.

generate_tokens para texto

generate_tokens() acepta una función que devuelve strings.

from io import StringIO
from tokenize import generate_tokens

for item in generate_tokens(StringIO("x = 1\n").readline):
    print(item)

No produce ENCODING. Para archivos reales, prefiere bytes o tokenize.open().

Encoding del fuente

Los archivos Python pueden declarar encoding en las primeras líneas. tokenize() lo detecta según las reglas del lenguaje.

Decodificar todo como UTF-8 antes puede fallar en proyectos legacy.

detect_encoding

detect_encoding() devuelve encoding y líneas ya consumidas.

from tokenize import detect_encoding

with open("modulo.py", "rb") as archivo:
    encoding, lineas = detect_encoding(archivo.readline)
    print(encoding, lineas)

Puede leer hasta dos líneas para revisar BOM y cookie.

tokenize.open

tokenize.open(filename) abre un fuente usando la codificación detectada.

import tokenize

with tokenize.open("modulo.py") as archivo:
    codigo = archivo.read()

Es una opción segura para herramientas de análisis.

Comentarios

A diferencia de AST, la tokenización conserva comentarios como COMMENT.

import token

comentarios = [
    item for item in tokens
    if item.type == token.COMMENT
]

Permite encontrar TODOs, pragmas, type comments y directivas.

No todo comentario es directiva

Una directiva necesita prefijo, posiciones válidas y reglas de parsing. Buscar una substring produce falsos positivos.

Define una sintaxis como # herramienta:.

NL frente a NEWLINE

NEWLINE termina una instrucción lógica. NL representa un salto físico que no la termina, por ejemplo dentro de paréntesis.

resultado = (
    1
    + 2
)

Formatters y analizadores de líneas deben distinguirlos.

Indentación

INDENT y DEDENT describen cambios de bloque.

if activo:
    ejecutar()

INDENT contiene el whitespace real. Tabs y espacios inconsistentes pueden generar error.

Errores de indentación

Tokenización o compilación puede lanzar IndentationError o TabError. Muestra archivo, posición y contexto.

No reescribas indentación ambigua sin una política documentada.

Strings

Un literal completo suele aparecer como token STRING, incluyendo prefijo y comillas.

r"ruta\archivo"
f"valor={x}"

Los detalles de f-strings y sintaxis nueva pueden variar por versión. Para expresiones internas quizá necesites parser.

Números

Enteros, floats, complex y bases diferentes aparecen como NUMBER con la grafía original.

0xff
1_000_000
3.14e-2

Esto preserva underscores y estilo.

Nombres y keywords

Identificadores y keywords son NAME. Usa keyword.iskeyword().

import keyword

if item.type == token.NAME and keyword.iskeyword(item.string):
    print("keyword", item.string)

Soft keywords dependen del contexto sintáctico.

untokenize

untokenize() reconstruye código.

from tokenize import untokenize

nuevo_codigo = untokenize(tokens)

Conserva el round trip de tipo y string, aunque el spacing exacto puede cambiar.

Transformación simple

Una herramienta puede reemplazar nombres seleccionados.

import token
from tokenize import TokenInfo, untokenize

nuevos = []
for item in tokens:
    if item.type == token.NAME and item.string == "antiguo":
        item = TokenInfo(
            item.type, "nuevo", item.start, item.end, item.line
        )
    nuevos.append(item)

resultado = untokenize(nuevos)

Un rename correcto considera scopes, atributos, imports y shadowing. Los tokens solos no resuelven semántica.

Pares tipo-string

untokenize() también acepta pares (type, string) y decide el spacing.

Conservar TokenInfo aporta contexto, pero las posiciones antiguas quedan obsoletas después de editar.

Posiciones tras cambios

Cambiar la longitud de un token invalida offsets posteriores. El fuente reconstruido puede ser válido, pero los diagnósticos necesitan remapping.

Una herramienta editorial robusta mantiene un source map.

Preservación de comentarios

Transformaciones AST y ast.unparse() suelen perder comentarios. Los tokens los conservan, pero refactoring estructural complejo es difícil.

Para round trip fiel, considera una concrete syntax tree.

TokenError

TokenError aparece en strings multilínea o brackets sin cerrar.

from tokenize import TokenError

try:
    tokens = list(tokenize(readline))
except TokenError as error:
    print("fuente incompleto", error)

En editores, código temporalmente incompleto es normal.

ERRORTOKEN

Caracteres inválidos y casos especiales pueden aparecer como ERRORTOKEN. Inspecciona texto y posición antes de diagnosticar.

No etiquetes todo error token como entrada hostil.

Buffers parciales

Una IDE puede tokenizar mientras el usuario escribe. Implementa debounce, cancelación y resultados parciales.

No hace falta ejecutar el código.

Archivos grandes

Convertir el generator en lista consume memoria proporcional al tamaño. Procesa en streaming cuando sea posible.

Usa una ventana limitada para lookahead.

Límites contra abuso

Entrada no confiable puede contener archivos enormes, líneas gigantes y nesting extremo. Limita bytes, líneas, tokens y tiempo.

Aísla análisis pesado en otro proceso para servicios públicos.

Identificadores Unicode

Python admite identificadores Unicode. No asumas ASCII.

Las reglas de seguridad pueden detectar caracteres confusos sin rechazar idiomas legítimos.

Caracteres invisibles

Una herramienta puede reportar controles, espacios inusuales o caracteres bidireccionales. Diferencia uso legítimo de riesgo.

Muestra code points y posiciones.

Combina con AST

Usa tokens para comentarios y grafía y AST para estructura. Un flujo común asocia nodos con rangos y localiza tokens.

Consulta ast en Python.

Combina con symtable

Tokens muestran grafía; symtable identifica scopes, locals, globals y free variables.

La combinación es más segura para renames.

Formatters

Un formatter debe entender tokens, sintaxis, comentarios y reglas de layout. Añadir espacios alrededor de todo OP no basta.

Usa gramática completa y tests extensos.

Linters de comentarios

La tokenización basta para reglas sobre longitud, TODO sin responsable o pragma inválida.

Un # dentro de string no es token COMMENT.

Detección de secrets

Tokens pueden ayudar a encontrar strings asociadas a nombres como password, pero el análisis léxico genera falsos positivos.

Nunca registres el valor detectado.

Línea de comandos

El módulo ofrece una CLI para mostrar tokens.

python -m tokenize modulo.py

Es útil para aprender y depurar reglas.

Pruebas

Incluye encodings alternativos, BOM, comentarios, strings multilínea, f-strings, tabs, líneas vacías, brackets abiertos, Unicode, archivos incompletos y entrada grande.

Tras transformar, tokeniza y compila el resultado.

Errores comunes

Los fallos frecuentes son leer todo como UTF-8, confundir NL y NEWLINE, tratar keywords como tipo separado, renombrar NAME sin scope, perder comentarios al pasar a AST, confiar en posiciones antiguas, materializar listas enormes y no limitar entrada pública.

Conclusión

tokenize expone la forma léxica del código Python conservando comentarios, grafía, líneas y operadores. Usa tokenize.open() para encoding correcto, exact_type para operadores y untokenize() para reconstrucción.

Combina tokens con AST y tablas de símbolos cuando necesites contexto semántico. Consulta la documentación oficial de tokenize y la documentación de token.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Side view of contemplating female assistant in casual style standing near shelves and choosing file with documents
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    zipapp en Python: crea archivos .pyz

    Aprende zipapp en Python para crear archivos .pyz, definir entry points, incluir dependencias puras, usar recursos y distribuir CLIs seguras.

    Ler mais

    Tempo de leitura: 6 minutos
    27/08/2026
    High-angle view of woman coding on a laptop, with a Python book nearby. Ideal for programming and tech content.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    sysconfig en Python: rutas y build

    Aprende sysconfig en Python para descubrir rutas, schemes, headers, flags de build, ABI, extensiones nativas y entornos virtuales.

    Ler mais

    Tempo de leitura: 6 minutos
    27/08/2026
    Código binario verde sobre el teclado de un portátil, representando datos internos de Python.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    marshal en Python: formato interno

    Aprende marshal en Python para objetos internos y bytecode, con versiones, allow_code, caches descartables, límites y riesgos de entrada no

    Ler mais

    Tempo de leitura: 6 minutos
    27/08/2026
    Vibrant assortment of pickled vegetables in jars with red fabric covers, displayed on shelves.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    copyreg en Python: personaliza pickle

    Aprende copyreg en Python para personalizar pickle, registrar reducers, versionar estado, evitar conflictos globales y serializar con seguridad.

    Ler mais

    Tempo de leitura: 6 minutos
    27/08/2026
    A developer typing code on a laptop with a Python book beside in an office.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    reprlib en Python: objetos resumidos

    Aprende reprlib en Python para resumir listas, strings y objetos recursivos, limitar logs y crear representaciones seguras y legibles.

    Ler mais

    Tempo de leitura: 6 minutos
    27/08/2026
    Close-up view of a computer screen displaying code in a software development environment.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    graphlib en Python: orden topológico

    Aprende graphlib en Python para ordenar dependencias, detectar ciclos, ejecutar tareas listas en paralelo y crear pipelines seguros.

    Ler mais

    Tempo de leitura: 7 minutos
    27/08/2026