linecache — Lectura eficiente de archivos de texto¶
Propósito: | Recupera líneas de texto de archivos o módulos Python importados, manteniendo un caché de los resultados para hacer del leer muchas líneas del mismo archivo más eficiente. |
---|
El módulo linecache
se usa en otras partes de la biblioteca estándar de
Python cuando se trata con archivos fuente de Python. La implementación de la
memoria caché mantiene el contenido de los archivos, analizados en líneas
separadas, en memoria. La interfaz devuelve las líneas solicitadas por índice
en una list
, y ahorra tiempo al leer repetidamente el archivo y analizando
las líneas para encontrar la deseada. Esto es especialmente útil cuando se
buscan varias líneas del mismo archivo, como cuando se produce un rastreo de un
informe de error.
Datos de prueba¶
Este texto producido por un generador de Lorem Ipsum se utiliza como entrada de muestra.
import os
import tempfile
lorem = '''Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. Vivamus eget elit. In posuere mi non
risus. Mauris id quam posuere lectus sollicitudin
varius. Praesent at mi. Nunc eu velit. Sed augue massa,
fermentum id, nonummy a, nonummy sit amet, ligula. Curabitur
eros pede, egestas at, ultricies ac, apellentesque eu,
tellus.
Sed sed odio sed mi luctus mollis. Integer et nulla ac augue
convallis accumsan. Ut felis. Donec lectus sapien, elementum
nec, condimentum ac, interdum non, tellus. Aenean viverra,
mauris vehicula semper porttitor, ipsum odio consectetuer
lorem, ac imperdiet eros odio a sapien. Nulla mauris tellus,
aliquam non, egestas a, nonummy et, erat. Vivamus sagittis
porttitor eros.'''
def make_tempfile():
fd, temp_file_name = tempfile.mkstemp()
os.close(fd)
with open(temp_file_name, 'wt') as f:
f.write(lorem)
return temp_file_name
def cleanup(filename):
os.unlink(filename)
Lectura de líneas específicas¶
Los números de línea de los archivos leídos por el módulo linecache
empiezan con 1, pero normalmente las listas comienzan a indexar la matriz desde
0.
import linecache
from linecache_data import *
filename = make_tempfile()
# Pick out the same line from source and cache.
# (Notice that linecache counts from 1)
print('SOURCE:')
print('{!r}'.format(lorem.split('\n')[4]))
print()
print('CACHE:')
print('{!r}'.format(linecache.getline(filename, 5)))
cleanup(filename)
Cada línea devuelta incluye una nueva línea al final.
$ python3 linecache_getline.py
SOURCE:
'fermentum id, nonummy a, nonummy sit amet, ligula. Curabitur'
CACHE:
'fermentum id, nonummy a, nonummy sit amet, ligula. Curabitur\n'
Manipulación de líneas en blanco¶
El valor de retorno siempre incluye la nueva línea al final de la línea, así que si la línea está vacía, el valor de retorno es solo la nueva línea.
import linecache
from linecache_data import *
filename = make_tempfile()
# Blank lines include the newline
print('BLANK : {!r}'.format(linecache.getline(filename, 8)))
cleanup(filename)
La línea ocho del archivo de entrada no contiene texto.
$ python3 linecache_empty_line.py
BLANK : '\n'
Manejo de errores¶
Si el número de línea solicitado cae fuera del rango de líneas válidas en el
archivo, getline()
devuelve una cadena vacía.
import linecache
from linecache_data import *
filename = make_tempfile()
# The cache always returns a string, and uses
# an empty string to indicate a line which does
# not exist.
not_there = linecache.getline(filename, 500)
print('NOT THERE: {!r} includes {} characters'.format(
not_there, len(not_there)))
cleanup(filename)
El archivo de entrada solo tiene 15 líneas, por lo que solicitar la línea 500 es como tratar de leer más allá del final del archivo.
$ python3 linecache_out_of_range.py
NOT THERE: '' includes 0 characters
La lectura de un archivo que no existe se maneja de la misma manera.
import linecache
# Errors are even hidden if linecache cannot find the file
no_such_file = linecache.getline(
'this_file_does_not_exist.txt', 1,
)
print('NO FILE: {!r}'.format(no_such_file))
El módulo nunca genera una excepción cuando la persona que llama intenta leer datos.
$ python3 linecache_missing_file.py
NO FILE: ''
Lectura de archivos fuente de Python¶
Como linecache
se usa mucho cuando se producen rastreos, una de sus
características clave es la capacidad de encontrar módulos fuente de Python en
la ruta de importación especificando el nombre base del módulo.
import linecache
import os
# Look for the linecache module, using
# the built in sys.path search.
module_line = linecache.getline('linecache.py', 3)
print('MODULE:')
print(repr(module_line))
# Look at the linecache module source directly.
file_src = linecache.__file__
if file_src.endswith('.pyc'):
file_src = file_src[:-1]
print('\nFILE:')
with open(file_src, 'r') as f:
file_line = f.readlines()[2]
print(repr(file_line))
El código para poblar el caché en linecache
busca en sys.path
el módulo
nombrado si no puede encontrar un archivo con ese nombre en el directorio
actual. Este ejemplo busca linecache.py
. Como no hay una copia en el
directorio actual, el archivo de la biblioteca estándar es encontrado en su
lugar.
$ python3 linecache_path_search.py
MODULE:
'This is intended to read lines from modules imported -- hence
if a filename\n'
FILE:
'This is intended to read lines from modules imported -- hence
if a filename\n'