Python — обработка перехода на n-й строке с помощью readlines()

Я пытаюсь исправить сломанную библиотеку, которую хочу использовать на Github.

Я локально «исправил» проблему. но я не думаю, что это очень чистый метод...

Я роюсь в библиотеке WARC в интернет-архиве, особенно в части arc.py (https://github.com/internetarchive/warc/blob/master/warc/arc.py).

С тех пор, как была написана библиотека, инструменты, которые создают файлы ARC, немного изменились, и в результате встроенный анализатор дает сбой, поскольку он не ожидает увидеть некоторые метаданные в файле.

Мое локальное исправление выглядит так:

    if header.startswith("<arcmetadata"):
        while not header.endswith("</arcmetadata>\n"):
            header = self.fileobj.readline()
        header = self.fileobj.readline()
        header = self.fileobj.readline()

И я не уверен, что мой вызов readlines() дважды, чтобы удалить следующие две пустые строки (содержащие "/n", является самым чистым способом продвижения по файловому объекту.

Это хороший питон? или есть лучший способ?


person Jay Gattuso    schedule 25.11.2013    source источник


Ответы (3)


Код выглядит как ошибка копирования/вставки. Нет ничего плохого в использовании .readline(), просто задокументируйте, что вы делаете:

# skip metadata
if header.startswith("<arcmetadata"):
    while not header.endswith("</arcmetadata>\n"):
        header = self.fileobj.readline()
    #NOTE: header ends with `"</arc..."` here i.e., it is not blank

# skip blank lines
while not header.strip():
    header = self.fileobj.readline()

Кстати, если файл содержит xml, используйте парсер xml для его анализа. Не делайте этого вручную.

person jfs    schedule 26.11.2013

Хотя в том, что вы делаете, нет ничего плохого по своей сути, было бы более семантически написать:

next(self.fileobj, None)

без присвоения переменной, чтобы показать, что вы бросаете следующую строку.

person Joel Cornett    schedule 25.11.2013

Здесь может пригодиться itertools

from itertools import islice, dropwhile
if header.startswith("<arcmetadata"):
    fileobj = dropwhile(lambda x: not x.endswith("</arcmetadata>\n"), fileobj)
    fileobj = islice(fileobj, 2, None)
person iruvar    schedule 26.11.2013