linecache en Python: lee líneas del código

Publicado el: 27/08/2026
Tempo de leitura: 8 minutos
A close-up shot showcasing the intricate scales of a snake, highlighting texture and color.

El módulo linecache permite acceder eficientemente a líneas concretas de archivos de texto, con soporte especial para código fuente Python. Herramientas como traceback, debuggers, inspectores y analizadores lo utilizan para recuperar la línea asociada a un frame sin abrir y recorrer el archivo completo en cada consulta.

La API es pequeña, pero su comportamiento incluye un cache global del proceso, invalidación, reglas de encoding y soporte para módulos cargados mediante import hooks. Comprender estos detalles ayuda a construir diagnósticos, navegadores de código, editores y sistemas de informes más fiables.

Lee una línea

La función principal es linecache.getline(filename, lineno). La numeración comienza en 1.

import linecache

linea = linecache.getline("aplicacion.py", 12)
print(linea)

Un resultado correcto suele incluir la nueva línea final. Cuando el archivo o número no puede leerse, la función normalmente devuelve una string vacía en lugar de lanzar errores comunes de archivo.

La numeración comienza en uno

A diferencia de las listas Python, la primera línea es la línea 1. Esto coincide con tracebacks, editores, mensajes del compilador y posiciones de AST.

primera = linecache.getline("app.py", 1)

Valida números proporcionados por usuarios para evitar confusiones con cero, negativos o valores enormes.

Interpreta el resultado vacío

Una string vacía puede significar que el archivo no existe, la línea está fuera del rango, la lectura falló o el fuente no está disponible. La API está orientada a diagnósticos, donde no mostrar el fragmento es preferible a ocultar la excepción original.

Si necesitas distinguir causas, valida la ruta y lee el archivo directamente con manejo explícito de errores.

El cache global

Después de cargar un archivo, linecache mantiene información en un cache global del proceso. Las consultas posteriores evitan reabrir y recorrer el mismo archivo.

Esto resulta útil cuando un traceback necesita varias líneas. Las herramientas de larga duración deben considerar archivos desactualizados y memoria retenida.

Actualiza archivos modificados

checkcache() compara metadatos y elimina entradas aparentemente antiguas.

linecache.checkcache("aplicacion.py")
linea = linecache.getline("aplicacion.py", 12)

Sin filename, revisa las entradas apropiadas. Un editor o servidor de desarrollo puede ejecutarlo antes de mostrar fuente que quizá cambió.

Limpia el cache

clearcache() elimina todas las líneas almacenadas.

linecache.clearcache()

Es útil después de un análisis grande, al cambiar de workspace o cuando un proceso largo necesita liberar fuente.

No limpies en cada consulta

Limpiar constantemente elimina el beneficio de rendimiento. Invalida cuando exista un cambio conocido, al cerrar un proyecto o cuando las métricas muestren presión real de memoria.

Un file watcher puede llamar a checkcache() para paths modificados.

Usa module_globals cuando corresponda

getline() acepta un argumento opcional module_globals. Puede ayudar a encontrar fuente para módulos cuyo loader proporciona código sin archivo convencional.

linea = linecache.getline(
    filename,
    numero,
    module_globals=globals_modulo,
)

Esto importa para import hooks, módulos frozen, zip imports y loaders personalizados.

Loaders y get_source

Cuando existe un loader compatible, linecache puede pedir el código al sistema de importación, normalmente mediante get_source(). Por eso un traceback puede mostrar fuente aunque el filename no sea una ruta normal.

Los loaders personalizados deberían implementar correctamente los contratos para cooperar con debuggers y diagnósticos.

Fuente dentro de ZIP

Las aplicaciones distribuidas como ZIP o archivos .pyz pueden ejecutar módulos sin extraerlos. Un loader todavía puede exponer el fuente.

Consulta zipapp en Python para crear archivos ejecutables.

Código generado

El código compilado dinámicamente puede utilizar un filename simbólico en compile(). Si no existe archivo, cache o loader asociado, linecache no podrá recuperar la línea.

Los frameworks que generan código deberían conservar un mapeo controlado entre filenames simbólicos y fuente cuando el diagnóstico lo requiera.

Tracebacks

El módulo traceback usa linecache para mostrar la línea correspondiente a cada frame.

try:
    ejecutar()
except Exception:
    traceback.print_exc()

Si el archivo cambia después de cargar el código, la línea mostrada puede no coincidir con el bytecode en ejecución. Esto ocurre en deploys que sustituyen archivos sin reiniciar procesos.

Mantén código y fuente alineados

Evita modificar archivos usados por un proceso vivo. El runtime ejecuta code objects antiguos mientras el diagnóstico puede leer texto nuevo.

Deploys atómicos con directorios versionados y restart controlado conservan tracebacks correctos.

Encoding de fuente Python

Los archivos Python pueden declarar encoding. Linecache coopera con la maquinaria de lectura de fuente del intérprete.

Para leer un archivo completo explícitamente, usa tokenize.open(). Consulta tokenize en Python.

Nueva línea final

Las líneas devueltas normalmente incluyen \n. Elimina solamente esa nueva línea cuando la interfaz lo necesite.

texto = linecache.getline(ruta, numero).rstrip("\n")

No uses strip() indiscriminadamente porque elimina la indentación significativa.

Conserva la indentación

El whitespace muestra la estructura de bloques y afecta la sintaxis. Eliminarlo dificulta el diagnóstico y desalineará marcadores de columna.

Mantén la línea original y renderiza indicadores por separado.

Marcadores de columna

Linecache recupera texto, pero no interpreta offsets. SyntaxError, tokens y AST pueden proporcionar posiciones.

linea = linecache.getline(error.filename, error.lineno)
marcador = " " * (error.offset - 1) + "^"

Tabs, Unicode y offsets en bytes requieren cuidado. Usa tokenizer o AST para integración precisa con editores.

Muestra contexto cercano

Un diagnóstico puede incluir líneas antes y después.

def contexto(ruta, linea, radio=2):
    inicio = max(1, linea - radio)
    fin = linea + radio
    return [
        (numero, linecache.getline(ruta, numero))
        for numero in range(inicio, fin + 1)
    ]

Detén la salida al obtener valores vacíos más allá del archivo y limita el radio para reducir ruido.

Diagnósticos más claros

Linters y validadores pueden combinar filename, línea, columna, mensaje y fragmento.

config.py:18:7: valor inválido
    timeout = -1
          ^

No copies archivos completos a logs. Un contexto corto es más legible y seguro.

Seguridad de rutas

No aceptes una ruta arbitraria de usuario y la pases directamente a linecache. La función puede leer archivos accesibles por el proceso.

Restringe consultas a un workspace conocido, resuelve la ruta y confirma que el resultado permanece dentro de la raíz permitida.

from pathlib import Path

raiz = Path("proyecto").resolve()
objetivo = (raiz / ruta_usuario).resolve()
if objetivo != raiz and raiz not in objetivo.parents:
    raise ValueError("archivo fuera del proyecto")

Considera symlinks, permisos y cambios entre validación y lectura.

Privacidad

Las líneas de código pueden contener endpoints internos, nombres de clientes, consultas o secretos mal almacenados. Trata los fragmentos como datos sensibles.

Sanitiza informes enviados a servicios externos y aplica controles de acceso y retención.

Concurrencia

El cache es global al proceso. Las threads pueden consultar, pero invalidación y fuente mutable implican que el resultado no es un snapshot transaccional.

Para análisis consistente, lee el archivo una vez y conserva una copia inmutable propia.

Procesos separados

Cada proceso tiene su cache. Limpiar en el padre no afecta a los workers.

Los analizadores distribuidos deberían devolver diagnósticos compactos en lugar de asumir fuente compartida.

Uso de memoria

Analizar miles de archivos puede retener mucho texto. Llama a clearcache() al terminar un repositorio o lote.

Mide antes de optimizar: para tracebacks normales, el cache puede ser pequeño y útil.

Archivos enormes

Linecache está diseñado para fuente, no para consultas aleatorias sobre datasets gigantes. La carga puede mantener una lista completa de líneas.

Para logs enormes usa índices, seek, mmap o formatos de acceso aleatorio.

Archivos temporales

Si un archivo temporal se elimina después de entrar al cache, las consultas pueden seguir devolviendo líneas antiguas hasta una invalidación.

Esto puede preservar un traceback tardío, pero también confundir una herramienta que espera el filesystem actual.

Limitaciones de metadatos

La validación se basa en metadatos disponibles. Filesystems con resolución temporal baja, sincronización de red o sustituciones rápidas pueden producir casos inesperados.

Cuando la identidad exacta importa, usa paths de build inmutables o hashes en tu propia capa.

Notebooks y código interactivo

Los entornos interactivos generan filenames simbólicos y mantienen caches adicionales. Un nombre entre signos de menor y mayor puede no representar un archivo real.

Trata la disponibilidad del fuente como opcional en notebooks, REPLs y funciones dinámicas.

Integración con inspect

inspect.getsource() también depende de información de archivo y cache para recuperar funciones y clases.

Builtins, extensiones nativas y código generado pueden no tener fuente. Maneja la ausencia como resultado normal.

Integración con faulthandler

faulthandler produce pilas mínimas durante fallos graves. Después, las herramientas pueden usar linecache para enriquecer filenames y líneas cuando el fuente correspondiente existe.

Consulta faulthandler en Python.

Pruebas

Prueba primera y última línea, archivo ausente, número fuera del rango, encoding no UTF, archivo modificado, cache limpio, loader personalizado, módulo ZIP y ruta hostil.

Usa archivos temporales controlados y limpia el cache entre tests para evitar dependencia de orden.

No dependas de internals

El diccionario interno de cache existe, pero su formato exacto no es una API estable. Prefiere getline(), checkcache() y clearcache().

Aísla cualquier integración con fuente virtual y pruébala en cada versión soportada.

Cuándo leer directamente

Usa Path.read_text() o tokenize.open() cuando necesites todo el archivo, errores explícitos, snapshot inmutable o control completo de encoding.

Usa linecache para recuperar rápidamente una línea de diagnóstico.

Errores comunes

Los fallos frecuentes son usar índices desde cero, interpretar todo resultado vacío como línea vacía real, eliminar indentación, olvidar cache antiguo, aceptar rutas arbitrarias, usar el módulo para datos enormes y asumir que el fuente actual coincide con el código ejecutado.

Conclusión

linecache es una pieza pequeña pero esencial del diagnóstico de Python. Usa getline() para líneas puntuales, checkcache() cuando los archivos cambian y clearcache() después de lotes grandes.

Conserva indentación, protege paths y no trates el cache global como snapshot inmutable. Consulta la documentación oficial de linecache y tokenize en Python.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Close-up view of a computer screen displaying code in a software development environment.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    faulthandler en Python: diagnostica fallos

    Aprende faulthandler en Python para diagnosticar crashes, deadlocks, señales fatales, timeouts y bloqueos con dumps de todas las threads.

    Ler mais

    Tempo de leitura: 9 minutos
    27/08/2026
    A detailed image of a reticulated python showcasing its patterned scales and intricate skin texture.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    symtable en Python: analiza scopes

    Aprende symtable en Python para analizar scopes, locals, globals, parámetros, imports, nonlocals, closures y namespaces del compilador.

    Ler mais

    Tempo de leitura: 9 minutos
    27/08/2026
    Detailed shot of a Jungle Carpet Python (Morelia spilota cheynei) in its natural habitat.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    dis en Python: entiende el bytecode

    Aprende dis en Python para inspeccionar bytecode, jumps, stack effects, caches adaptativos y optimizaciones sin depender de internals inestables.

    Ler mais

    Tempo de leitura: 5 minutos
    27/08/2026
    Gold Bitcoin coins displayed on a sparkling gold texture, representing digital currency and finance.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    tokenize en Python: lee tokens del código

    Aprende tokenize en Python para leer tokens, comentarios, encoding, indentación y posiciones, además de transformar y reconstruir código con seguridad.

    Ler mais

    Tempo de leitura: 6 minutos
    27/08/2026
    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