Для чего StringIO в python используется в реальности? - PullRequest
64 голосов
/ 03 ноября 2011

Я не профессионал, и я ломал голову над пониманием того, для чего именно используется StringIO.Я искал в интернете несколько примеров.Однако почти все примеры очень абстрактны.И они просто показывают, «как» его использовать.Но никто из них не показывает «почему» и «при каких обстоятельствах» следует / будет использовать это?Заранее спасибо

ps, чтобы не путать этот вопрос со стековым потоком: Использование StringIO , которое сравнивает строку и StringIo.

Ответы [ 7 ]

78 голосов
/ 03 ноября 2011

Используется, когда у вас есть API, который принимает только файлы, но вам нужно использовать строку. Например, чтобы сжать строку с помощью модуля gzip в Python 2:

import gzip
import StringIO

stringio = StringIO.StringIO()
gzip_file = gzip.GzipFile(fileobj=stringio, mode='w')
gzip_file.write('Hello World')
gzip_file.close()

stringio.getvalue()
31 голосов
/ 03 ноября 2011

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

Например, скажем, у вас есть регистратор, который записывает данные в файл, и вы хотите вместо этого отправить выходные данные журнала по сети. Вы можете прочитать файл и записать его содержимое в сеть, или вы можете записать журнал в объект StringIO и отправить его по назначению в сеть, не касаясь файловой системы. StringIO позволяет легко сделать это первым способом, а затем переключиться на второй способ.

17 голосов
/ 03 ноября 2011

В тех случаях, когда вам нужен файлоподобный объект, который ACTS похож на файл, но записывает в строковый буфер в памяти: StringIO - это инструмент. Если вы создаете большие строки, такие как текстовые документы, и делаете много конкатенации строк, вам может оказаться проще просто использовать StringIO вместо набора операций типа mystr += 'more stuff\n'.

9 голосов
/ 04 ноября 2011

Я только что использовал StringIO на практике для двух вещей:

  • Для модульного тестирования скрипта, который выполняет много операций print, перенаправив sys.stdout в StringIO экземпляр для простого анализа;
  • Чтобы создать гарантированный правильно сформированный XML-документ (пользовательский запрос API), используя ElementTree, а затем write его для отправки через HTTP-соединение.

Не то чтобы вам нужно StringIO часто , но иногда это довольно полезно.

9 голосов
/ 03 ноября 2011

Несколько вещей, которые я лично использовал для:

  1. Кэширование всего файла. У меня есть сценарий, который читает PDF-файлы и выполняет проверку различных вещей о них. Используемая мной библиотека PDF берет открытый файл в конструкторе документов. Первоначально я только что открыл PDF, который мне было интересно читать, однако, когда я изменил его, чтобы сразу прочитать весь файл в память, а затем передать объект StringIO в библиотеку PDF, время выполнения моего скрипта сократилось вдвое.

  2. Отложенная печать. Тот же сценарий печатает заголовок перед каждым файлом PDF, который он читает. Тем не менее, я могу указать в командной строке, игнорировать ли определенные тесты, которые есть в его файле конфигурации, или включать только определенные. Если я проигнорирую все тесты для данного PDF, я не хочу печатать заголовок, но я не буду знать, сколько тестов я выполнил, пока не закончу запуск тестов (тесты могут быть определены динамически также). Поэтому я записываю заголовок в объект StringIO, изменяя sys.stdout, чтобы он указывал на него, и каждый раз, когда я запускаю тест, я проверяю, есть ли в этом объекте что-либо. Если это так, я печатаю его и сбрасываю. Вуаля, только PDF-файлы с тестами имеют напечатанные заголовки.

1 голос
/ 25 мая 2018

Я использовал его вместо текстовых файлов для юнит-тестирования.

Например, чтобы создать csv-файл для тестирования с пандами (Python 3):

import io
f = io.StringIO("id,name\n1,brian\n2,amanda\n3,zoey\n")
df = pd.read_csv(f) # pandas takes a file path or a file-like object

Из документации здесь :

Поток в памяти для текстового ввода-вывода.Текстовый буфер отбрасывается при вызове метода close ().

Начальное значение буфера можно установить, указав initial_value.

метод getvalue (): возвращает строку, содержащую весьсодержимое буфера.

0 голосов
/ 10 января 2017

Django имеет функцию call_command, которая используется для вызова команд управления.Эта функция печатает вывод на стандартный вывод и не возвращает никакого значения.Если вы хотите узнать, была ли команда выполнена успешно или нет, вы должны посмотреть на вывод и решить.

Используя StringIO, вы можете захватить вывод и проверить, является ли это желаемым выводом или нет.

with io.StringIO() as output:
    call_command('custom_command', stdout=output)
    if 'Success' not in output.getvalue():
        print('Custom command failed...')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...