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

    Rack de servidores que representa el balanceo de conexiones con SO_REUSEPORT_LB en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    SO_REUSEPORT_LB: reparte conexiones entre workers

    Aprende SO_REUSEPORT_LB en Python para distribuir conexiones entre workers con pruebas, portabilidad y cierre ordenado.

    Ler mais

    Tempo de leitura: 5 minutos
    11/10/2026
    Código Python asíncrono en un portátil para inspect.markcoroutinefunction
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    markcoroutinefunction: detecta wrappers async

    Aprende inspect.markcoroutinefunction en Python para identificar wrappers asíncronos, integrar frameworks y evitar detecciones incorrectas.

    Ler mais

    Tempo de leitura: 5 minutos
    10/10/2026
    Código Python para recorrer carpetas y archivos con Path.walk
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    Path.walk: recorre directorios con seguridad

    Aprende Path.walk en Python para recorrer directorios, filtrar archivos, tratar errores y controlar la travesía con seguridad.

    Ler mais

    Tempo de leitura: 5 minutos
    10/10/2026
    Depuración de un proceso Python en terminal con código
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    pdb -p: depura procesos Python en ejecución

    Aprende a conectar pdb a un proceso Python en ejecución, inspeccionar la pila y diagnosticar bloqueos de forma segura.

    Ler mais

    Tempo de leitura: 6 minutos
    09/10/2026
    Código Python para representar fracciones exactas
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    fractions.from_number: convierte números en fracciones

    Aprende fractions.from_number en Python para convertir números en fracciones exactas, controlar precisión, validar entradas y evitar redondeos inesperados.

    Ler mais

    Tempo de leitura: 4 minutos
    09/10/2026
    Desarrollador configurando un servidor HTTPS y certificado TLS con Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    HTTPSServer: crea un servidor HTTPS local en Python

    Aprende HTTPSServer en Python para crear servicios HTTPS locales, configurar certificados, usar hilos y comprender sus límites.

    Ler mais

    Tempo de leitura: 4 minutos
    08/10/2026