Автор оригинала: Doug Hellmann.
Цель:
Получение строк текста из файлов или импортированного Python модули, содержащие кеш результатов, чтобы сделать чтение многих строки из того же файла более эффективны.
Модуль linecache
используется в других частях стандартной библиотеки Python при работе с исходными файлами Python. Реализация кеша хранит в памяти содержимое файлов, разбитое на отдельные строки. API возвращает запрошенную строку (строки) путем индексации в list
и экономит время на многократное чтение файла и синтаксический анализ строк, чтобы найти нужную. Это особенно полезно при поиске нескольких строк в одном файле, например, при создании трассировки для отчета об ошибке.
Данные испытаний
Этот текст, созданный генератором Lorem Ipsum, используется как входной образец.
linecache_data.py
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)
Чтение определенных строк
Номера строк файлов, считываемых модулем linecache
, начинаются с 1, но обычно списки начинают индексировать массив с 0.
linecache_getline.py
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)
Каждая возвращенная строка включает завершающий символ новой строки.
$ 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'
Обработка пустых строк
Возвращаемое значение всегда включает новую строку в конце строки, поэтому, если строка пуста, возвращаемое значение – это просто новая строка.
linecache_empty_line.py
import linecache from linecache_data import * filename make_tempfile() # Blank lines include the newline print('BLANK : {!r}'.format(linecache.getline(filename, 8))) cleanup(filename)
В восьмой строке входного файла нет текста.
$ python3 linecache_empty_line.py BLANK : '\n'
Обработка ошибок
Если запрошенный номер строки выпадает из диапазона допустимых строк в файле, getline ()
возвращает пустую строку.
linecache_out_of_range.py
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)
Во входном файле всего 15 строк, поэтому запрос строки 500 похож на попытку чтения после конца файла.
$ python3 linecache_out_of_range.py NOT THERE: '' includes 0 characters
Таким же образом выполняется чтение из несуществующего файла.
linecache_missing_file.py
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))
Модуль никогда не вызывает исключения, когда вызывающий абонент пытается прочитать данные.
$ python3 linecache_missing_file.py NO FILE: ''
Чтение исходных файлов Python
Поскольку linecache
очень интенсивно используется при создании трассировок, одной из его ключевых функций является возможность найти исходные модули Python в пути импорта, указав базовое имя модуля.
linecache_path_search.py
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))
Код заполнения кеша в linecache
ищет в sys.path
названный модуль, если не может найти файл с таким именем в текущем каталоге. В этом примере выполняется поиск linecache.py
. Поскольку в текущем каталоге нет копии, вместо него будет найден файл из стандартной библиотеки.
$ 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'
Смотрите также