io — Основные инструменты для работы с потоками

Исходный код: Lib/io.py.


Обзор

Модуль io предоставляет основные средства Python для работы с различными типами ввода/вывода. Существует три основных типа ввода/вывода: текстовый ввод-вывод, двоичный ввод-вывод и сырьевой ввод-вывод. Это общие категории, и для каждой из них могут использоваться различные хранилища данных. Конкретный объект, принадлежащий к любой из этих категорий, называется file object. Другие распространенные термины - поток и файлоподобный объект.

Независимо от своей категории, каждый конкретный объект потока также будет обладать различными возможностями: он может быть только для чтения, только для записи или для чтения-записи. Он также может допускать произвольный произвольный доступ (поиск вперед или назад в любое место) или только последовательный доступ (например, в случае сокета или трубы).

Все потоки внимательно относятся к типу данных, которые вы им передаете. Например, передача объекта str методу write() двоичного потока вызовет ошибку TypeError. Также как и передача объекта bytes методу write() текстового потока.

Изменено в версии 3.3: Операции, которые раньше вызывали IOError, теперь вызывают OSError, поскольку IOError теперь является псевдонимом OSError.

Ввод/вывод текста

Текстовый ввод-вывод ожидает и производит объекты str. Это означает, что во всех случаях, когда хранилище данных изначально состоит из байтов (например, в случае файла), кодирование и декодирование данных производится прозрачно, также как и необязательный перевод специфических для платформы символов новой строки.

Проще всего создать текстовый поток с помощью команды open(), дополнительно указав кодировку:

f = open("myfile.txt", "r", encoding="utf-8")

Текстовые потоки в памяти также доступны в виде объектов StringIO:

f = io.StringIO("some initial text data")

API текстового потока подробно описан в документации к программе TextIOBase.

Двоичный ввод/вывод

Двоичный ввод/вывод (также называемый буферизованным вводом/выводом) ожидает bytes-like objects и производит объекты bytes. Не выполняется ни кодирование, ни декодирование, ни перевод новой строки. Эта категория потоков может использоваться для всех видов нетекстовых данных, а также когда требуется ручной контроль над обработкой текстовых данных.

Самый простой способ создать бинарный поток - это open() с 'b' в режиме string:

f = open("myfile.jpg", "rb")

Двоичные потоки в памяти также доступны в виде объектов BytesIO:

f = io.BytesIO(b"some initial binary data: \x00\x01")

API двоичного потока подробно описан в документации к BufferedIOBase.

Другие библиотечные модули могут предоставлять дополнительные способы создания текстовых или двоичных потоков. Например, смотрите socket.socket.makefile().

Необработанный ввод/вывод

Необработанный ввод-вывод (также называемый небуферизованным вводом-выводом) обычно используется как низкоуровневый строительный блок для двоичных и текстовых потоков; редко бывает полезно напрямую манипулировать необработанным потоком из пользовательского кода. Тем не менее, вы можете создать необработанный поток, открыв файл в двоичном режиме с отключенной буферизацией:

f = open("myfile.jpg", "rb", buffering=0)

API сырого потока подробно описан в документации RawIOBase.

Кодирование текста

По умолчанию кодировка TextIOWrapper и open() зависит от локали (locale.getpreferredencoding(False)).

Однако многие разработчики забывают указывать кодировку при открытии текстовых файлов, закодированных в UTF-8 (например, JSON, TOML, Markdown и т.д…), поскольку большинство платформ Unix по умолчанию используют локаль UTF-8. Это приводит к ошибкам, поскольку кодировка локали не является UTF-8 для большинства пользователей Windows. Например:

# May not work on Windows when non-ASCII characters in the file.
with open("README.md") as f:
    long_description = f.read()

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

Соответственно, настоятельно рекомендуется явно указывать кодировку при открытии текстовых файлов. Если вы хотите использовать UTF-8, передайте encoding="utf-8". Для использования текущей кодировки локали в Python 3.10 поддерживается encoding="locale".

Когда вам нужно запустить существующий код на Windows, который пытается открыть файлы UTF-8, используя кодировку локали по умолчанию, вы можете включить режим UTF-8. См. раздел UTF-8 mode on Windows.

Кодирование по желаниюПредупреждение

Добавлено в версии 3.10: Более подробную информацию см. в разделе PEP 597.

Чтобы узнать, где используется кодировка локали по умолчанию, вы можете включить опцию командной строки -X warn_default_encoding или установить переменную окружения PYTHONWARNDEFAULTENCODING, которая будет выдавать EncodingWarning, когда используется кодировка по умолчанию.

Если вы предоставляете API, который использует open() или TextIOWrapper и передает encoding=None в качестве параметра, вы можете использовать text_encoding(), чтобы вызывающие API выдавали EncodingWarning, если они не передают encoding. Однако, пожалуйста, рассмотрите возможность использования UTF-8 по умолчанию (т.е. encoding="utf-8") для новых API.

Высокоуровневый интерфейс модуля

io.DEFAULT_BUFFER_SIZE

Инт, содержащий размер буфера по умолчанию, используемый классами буферизованного ввода-вывода модуля. open() использует размер буфера файла (полученный с помощью os.stat()), если это возможно.

io.open(file, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

Это псевдоним для встроенной функции open().

Вызывает auditing event open с аргументами path, mode, flags.

io.open_code(path)

Открывает предоставленный файл в режиме 'rb'. Эту функцию следует использовать, если предполагается рассматривать содержимое файла как исполняемый код.

path должен быть str и абсолютный путь.

Поведение этой функции может быть отменено более ранним вызовом PyFile_SetOpenCodeHook(). Однако, если предположить, что path является str и абсолютным путем, open_code(path) всегда должна вести себя так же, как open(path, 'rb'). Переопределение поведения предназначено для дополнительной проверки или предварительной обработки файла.

Добавлено в версии 3.8.

io.text_encoding(encoding, stacklevel=2, /)

Это вспомогательная функция для вызываемых таблиц, которые используют open() или TextIOWrapper и имеют параметр encoding=None.

Эта функция возвращает encoding, если он не является None и "locale", если encoding является None.

Эта функция выдает предупреждение EncodingWarning, если sys.flags.warn_default_encoding истинно и encoding равно None. stacklevel указывает, где выдается предупреждение. Например:

def read_text(path, encoding=None):
    encoding = io.text_encoding(encoding)  # stacklevel=2
    with open(path, encoding) as f:
        return f.read()

В этом примере для вызывающего EncodingWarning выдается read_text().

Для получения дополнительной информации см. раздел Кодирование текста.

Добавлено в версии 3.10.

exception io.BlockingIOError

Это псевдоним совместимости для встроенного исключения BlockingIOError.

exception io.UnsupportedOperation

Исключение, наследующее OSError и ValueError, которое возникает при вызове неподдерживаемой операции над потоком.

См.также

sys

содержит стандартные потоки ввода-вывода: sys.stdin, sys.stdout и sys.stderr.

Иерархия классов

Реализация потоков ввода/вывода организована в виде иерархии классов. Сначала abstract base classes (ABCs), которые используются для указания различных категорий потоков, затем конкретные классы, предоставляющие стандартные реализации потоков.

Примечание

Абстрактные базовые классы также предоставляют реализации некоторых методов по умолчанию, чтобы облегчить реализацию конкретных классов потоков. Например, BufferedIOBase предоставляет неоптимизированные реализации readinto() и readline().

На вершине иерархии ввода-вывода находится абстрактный базовый класс IOBase. Он определяет базовый интерфейс потока. Обратите внимание, однако, что не существует разделения между чтением и записью в потоки; реализациям разрешено поднимать UnsupportedOperation, если они не поддерживают данную операцию.

ABC RawIOBase расширяет IOBase. Он работает с чтением и записью байтов в поток. FileIO подклассы RawIOBase для обеспечения интерфейса к файлам в файловой системе машины.

ABC BufferedIOBase расширяет IOBase. Он занимается буферизацией необработанного двоичного потока (RawIOBase). Его подклассы, BufferedWriter, BufferedReader и BufferedRWPair, буферизируют необработанные двоичные потоки, доступные для чтения, записи, а также для чтения и записи соответственно. BufferedRandom предоставляет буферизованный интерфейс для потоков с возможностью поиска. Другой подкласс BufferedIOBase, BytesIO, представляет собой поток байтов в памяти.

ABC TextIOBase расширяет IOBase. Он работает с потоками, байты которых представляют собой текст, и обрабатывает кодирование и декодирование в строки и из строк. TextIOWrapper, который расширяет TextIOBase, является интерфейсом буферизованного текста к буферизованному сырому потоку (BufferedIOBase). Наконец, StringIO - это поток текста в памяти.

Имена аргументов не являются частью спецификации, и только аргументы open() предназначены для использования в качестве аргументов ключевых слов.

В следующей таблице приведены ABC, предоставляемые модулем io:

ABC

Наследует

Методы заглушки

Методы и свойства миксинов

IOBase

fileno, seek и truncate.

close, closed, __enter__, __exit__, flush, isatty, __iter__, __next__, readable, readline, readlines, seekable, tell, writable и writelines.

RawIOBase

IOBase

readinto и write.

Наследуемые методы IOBase, read и readall

BufferedIOBase

IOBase

detach, read, read1 и write.

Наследуемые методы IOBase, readinto и readinto1

TextIOBase

IOBase

detach, read, readline и write.

Наследуемые методы IOBase, encoding, errors и newlines

Базовые классы ввода/вывода

class io.IOBase

Абстрактный базовый класс для всех классов ввода-вывода.

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

Даже если IOBase не объявляет read() или write(), поскольку их сигнатуры будут отличаться, реализации и клиенты должны считать эти методы частью интерфейса. Кроме того, реализации могут выдать ошибку ValueError (или UnsupportedOperation) при вызове операций, которые они не поддерживают.

Основным типом, используемым для чтения двоичных данных из файла или записи в файл, является bytes. Другие bytes-like objects также принимаются в качестве аргументов метода. Классы текстового ввода-вывода работают с данными str.

Обратите внимание, что вызов любого метода (даже запроса) на закрытом потоке не определен. В этом случае реализация может выдать ошибку ValueError.

IOBase (и его подклассы) поддерживает протокол итератора, что означает, что объект IOBase можно итерировать, получая строки в потоке. Строки определяются немного по-разному в зависимости от того, является ли поток двоичным (выдающим байты) или текстовым (выдающим символьные строки). См. readline() ниже.

IOBase также является менеджером контекста и поэтому поддерживает оператор with. В этом примере file закрывается после завершения набора операторов with - даже если возникает исключение:

with open('spam.txt', 'w') as file:
    file.write('Spam and eggs!')

IOBase предоставляет эти атрибуты и методы данных:

close()

Промыть и закрыть данный поток. Этот метод не имеет эффекта, если файл уже закрыт. После закрытия файла любая операция над ним (например, чтение или запись) вызовет ошибку ValueError.

Для удобства разрешается вызывать этот метод более одного раза; однако только первый вызов будет иметь эффект.

closed

True если поток закрыт.

fileno()

Возвращает базовый дескриптор файла (целое число) потока, если он существует. Если объект IO не использует файловый дескриптор, выдается сообщение OSError.

flush()

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

isatty()

Верните True, если поток является интерактивным (т.е. подключен к терминалу/tty-устройству).

readable()

Возвращает True, если из потока можно читать. Если False, то read() вызовет ошибку OSError.

readline(size=- 1, /)

Считывает и возвращает одну строку из потока. Если указан size, будет прочитано не более size байт.

Для двоичных файлов терминатором строки всегда является b'\n'; для текстовых файлов аргумент newline для open() может быть использован для выбора распознаваемого терминатора(ов) строки.

readlines(hint=- 1, /)

Считывает и возвращает список строк из потока. Можно указать hint для контроля количества прочитанных строк: если общий размер (в байтах/символах) всех строк превысит hint, то больше строк прочитано не будет.

hint значения 0 или меньше, а также None рассматриваются как отсутствие подсказки.

Обратите внимание, что уже сейчас можно выполнять итерацию по файловым объектам с помощью for line in file: ... без вызова file.readlines().

seek(offset, whence=SEEK_SET, /)

Изменить позицию потока на заданный байт offset. offset интерпретируется относительно позиции, указанной whence. Значение по умолчанию для whence равно SEEK_SET. Значениями для whence являются:

  • SEEK_SET или 0 – начало потока (по умолчанию); смещение должно быть нулевым или положительным

  • SEEK_CUR или 1 – текущая позиция потока; смещение может быть отрицательным

  • SEEK_END или 2 – конец потока; смещение обычно отрицательно

Возвращает новое абсолютное положение.

Добавлено в версии 3.1: Константы SEEK_*.

Добавлено в версии 3.3: Некоторые операционные системы могут поддерживать дополнительные значения, например os.SEEK_HOLE или os.SEEK_DATA. Допустимые значения для файла могут зависеть от того, открыт он в текстовом или двоичном режиме.

seekable()

Возвращает True, если поток поддерживает произвольный доступ. Если False, seek(), tell() и truncate(), то будет поднята оценка OSError.

tell()

Возвращает текущую позицию потока.

truncate(size=None, /)

Изменение размера потока до заданного size в байтах (или текущей позиции, если size не задан). Текущая позиция потока не изменяется. Изменение размера может расширить или уменьшить текущий размер файла. В случае расширения, содержимое новой области файла зависит от платформы (на большинстве систем дополнительные байты заполняются нулями). Возвращается новый размер файла.

Изменено в версии 3.5: Теперь Windows будет заполнять файлы нулями при расширении.

writable()

Возвращает True, если поток поддерживает запись. Если False, write() и truncate() вызовет OSError.

writelines(lines, /)

Запись списка строк в поток. Разделители строк не добавляются, поэтому обычно каждая из предоставленных строк имеет разделитель строк в конце.

__del__()

Подготовиться к уничтожению объекта. IOBase предоставляет реализацию этого метода по умолчанию, которая вызывает метод экземпляра close().

class io.RawIOBase

Базовый класс для необработанных двоичных потоков. Он наследует IOBase.

Необработанные двоичные потоки обычно обеспечивают низкоуровневый доступ к базовому устройству ОС или API, и не пытаются инкапсулировать его в высокоуровневые примитивы (эта функциональность осуществляется на более высоком уровне в буферизованных двоичных и текстовых потоках, описанных далее на этой странице).

RawIOBase предоставляет эти методы в дополнение к методам из IOBase:

read(size=- 1, /)

Считывает до size байт из объекта и возвращает их. Для удобства, если size не указан или -1, возвращаются все байты до EOF. В противном случае выполняется только один системный вызов. Меньше size байт может быть возвращено, если вызов операционной системы возвращает меньше size байт.

Если возвращается 0 байт, а size не был равен 0, это означает конец файла. Если объект находится в неблокирующем режиме и нет доступных байтов, возвращается None.

Реализация по умолчанию отклоняется на readall() и readinto().

readall()

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

readinto(b, /)

Считывает байты в предварительно выделенный, доступный для записи bytes-like object b и возвращает количество считанных байтов. Например, b может быть bytearray. Если объект находится в неблокирующем режиме и нет доступных байтов, возвращается None.

write(b, /)

Записать заданный bytes-like object, b, в базовый сырой поток и вернуть количество записанных байт. Это может быть меньше, чем длина b в байтах, в зависимости от специфики базового raw потока, особенно если он находится в неблокирующем режиме. None возвращается, если необработанный поток не блокируется, и в него не может быть легко записан ни один байт. Вызывающая сторона может освободить или изменить b после возврата этого метода, поэтому реализация должна обращаться к b только во время вызова метода.

class io.BufferedIOBase

Базовый класс для двоичных потоков, поддерживающих некоторую буферизацию. Он наследует IOBase.

Основное отличие от RawIOBase заключается в том, что методы read(), readinto() и write() будут пытаться (соответственно) прочитать столько входных данных, сколько запрошено, или потреблять все заданные выходные данные, за счет выполнения, возможно, более одного системного вызова.

Кроме того, эти методы могут поднять BlockingIOError, если базовый сырой поток находится в неблокирующем режиме и не может принять или отдать достаточно данных; в отличие от своих аналогов RawIOBase, они никогда не возвращают None.

Кроме того, метод read() не имеет реализации по умолчанию, которая отступает перед readinto().

Типичная реализация BufferedIOBase должна не наследоваться от реализации RawIOBase, а обертывать ее, как это делают BufferedWriter и BufferedReader.

BufferedIOBase предоставляет или переопределяет эти атрибуты и методы данных в дополнение к атрибутам и методам из IOBase:

raw

Основной необработанный поток (экземпляр RawIOBase), с которым работает BufferedIOBase. Это не является частью API BufferedIOBase и может отсутствовать в некоторых реализациях.

detach()

Отделите основной необработанный поток от буфера и верните его.

После отсоединения необработанного потока буфер находится в непригодном для использования состоянии.

Некоторые буферы, например BytesIO, не имеют концепции единого необработанного потока для возврата из этого метода. Они вызывают ошибку UnsupportedOperation.

Добавлено в версии 3.1.

read(size=- 1, /)

Считать и вернуть до size байт. Если аргумент опущен, None или отрицательный, данные считываются и возвращаются до достижения EOF. Если поток уже достиг EOF, возвращается пустой объект bytes.

Если аргумент положительный, а основной поток raw не является интерактивным, то для удовлетворения подсчета байтов может быть выполнено несколько считываний raw (если только EOF не будет достигнут первым). Но для интерактивных потоков raw будет выполнено не более одного чтения raw, и короткий результат не означает, что EOF неминуем.

Возникает ошибка BlockingIOError, если базовый сырой поток находится в неблокирующем режиме и не имеет доступных данных в данный момент.

read1(size=- 1, /)

Чтение и возврат до size байт, не более одного вызова метода read() (или readinto()) базового сырого потока. Это может быть полезно, если вы реализуете собственную буферизацию поверх объекта BufferedIOBase.

Если size равен -1 (по умолчанию), возвращается произвольное количество байт (больше нуля, если не достигнут EOF).

readinto(b, /)

Считывает байты в предварительно выделенный, доступный для записи bytes-like object b и возвращает количество считанных байтов. Например, b может быть bytearray.

Как и read(), может быть выполнено несколько чтений базового сырого потока, если последний не является интерактивным.

Возникает ошибка BlockingIOError, если базовый сырой поток находится в неблокирующем режиме и не имеет доступных данных в данный момент.

readinto1(b, /)

Считывание байтов в предварительно выделенный, доступный для записи bytes-like object b, используя не более одного вызова метода read() (или readinto()) базового сырого потока. Возвращает количество прочитанных байтов.

Возникает ошибка BlockingIOError, если базовый сырой поток находится в неблокирующем режиме и не имеет доступных данных в данный момент.

Добавлено в версии 3.5.

write(b, /)

Записывает заданный bytes-like object, b, и возвращает количество записанных байт (всегда равное длине b в байтах, так как в случае неудачи записи будет выдано OSError). В зависимости от фактической реализации, эти байты могут быть легко записаны в базовый поток или храниться в буфере по причинам производительности и задержки.

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

Вызывающая сторона может освободить или изменить b после возврата этого метода, поэтому реализация должна получить доступ к b только во время вызова метода.

Ввод/вывод необработанных файлов

class io.FileIO(name, mode='r', closefd=True, opener=None)

Необработанный двоичный поток, представляющий файл на уровне ОС, содержащий байтовые данные. Он наследует RawIOBase.

Имя* может быть одним из двух:

  • символьная строка или объект bytes, представляющий путь к файлу, который будет открыт. В этом случае closefd должен быть True (по умолчанию), иначе будет выдана ошибка.

  • целое число, представляющее номер существующего файлового дескриптора уровня ОС, к которому результирующий объект FileIO будет предоставлять доступ. Когда объект FileIO будет закрыт, этот fd также будет закрыт, если только closefd не установлено в False.

Режим mode может быть 'r', 'w', 'x' или 'a' для чтения (по умолчанию), записи, эксклюзивного создания или добавления. Файл будет создан, если он не существует, при открытии для записи или добавления; он будет усечен при открытии для записи. Если файл уже существует, то при открытии для создания будет выдан сигнал FileExistsError. Открытие файла для создания подразумевает запись, поэтому этот режим ведет себя аналогично 'w'. Добавьте '+' к режиму, чтобы разрешить одновременное чтение и запись.

Методы read() (при вызове с положительным аргументом), readinto() и write() этого класса будут выполнять только один системный вызов.

Пользовательский открыватель может быть использован путем передачи вызываемого объекта в качестве opener. Дескриптор файла, лежащий в основе объекта файла, можно получить, вызвав opener с (name, flags). opener должен возвращать открытый дескриптор файла (передача os.open в качестве opener приводит к функциональности, аналогичной передаче None).

Вновь созданный файл имеет номер non-inheritable.

Примеры использования параметра opener см. во встроенной функции open().

Изменено в версии 3.3: Добавлен параметр opener. Добавлен режим 'x'.

Изменено в версии 3.4: Теперь файл не наследуется.

FileIO предоставляет эти атрибуты данных в дополнение к атрибутам из RawIOBase и IOBase:

mode

Режим, заданный в конструкторе.

name

Имя файла. Это дескриптор файла, если имя не указано в конструкторе.

Буферизованные потоки

Буферизованные потоки ввода-вывода обеспечивают более высокоуровневый интерфейс к устройству ввода-вывода, чем необработанный ввод-вывод.

class io.BytesIO(initial_bytes=b'')

Двоичный поток, использующий буфер байтов в памяти. Он наследует BufferedIOBase. Буфер отбрасывается при вызове метода close().

Необязательный аргумент initial_bytes представляет собой bytes-like object, содержащий начальные данные.

BytesIO предоставляет или переопределяет эти методы в дополнение к методам из BufferedIOBase и IOBase:

getbuffer()

Возвращает доступное для чтения и записи представление содержимого буфера без его копирования. Кроме того, при изменении представления содержимое буфера будет прозрачно обновляться:

>>> b = io.BytesIO(b"abcdef")
>>> view = b.getbuffer()
>>> view[2:4] = b"56"
>>> b.getvalue()
b'ab56ef'

Примечание

Пока представление существует, объект BytesIO не может быть изменен в размерах или закрыт.

Добавлено в версии 3.2.

getvalue()

Возвращает bytes, содержащий все содержимое буфера.

read1(size=- 1, /)

В BytesIO это то же самое, что и read().

Изменено в версии 3.7: Аргумент size теперь является необязательным.

readinto1(b, /)

В BytesIO это то же самое, что и readinto().

Добавлено в версии 3.5.

class io.BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE)

Буферизованный двоичный поток, обеспечивающий высокоуровневый доступ к читаемому и не ищущему необработанному двоичному потоку RawIOBase. Он наследует BufferedIOBase.

При чтении данных из этого объекта больший объем данных может быть запрошен из базового необработанного потока и сохранен во внутреннем буфере. Затем буферизованные данные могут быть возвращены непосредственно при последующих чтениях.

Конструктор создает BufferedReader для заданного читаемого raw потока и buffer_size. Если buffer_size опущен, то используется DEFAULT_BUFFER_SIZE.

BufferedReader предоставляет или переопределяет эти методы в дополнение к методам из BufferedIOBase и IOBase:

peek(size=0, /)

Возвращает байты из потока без продвижения позиции. Для выполнения вызова выполняется не более одного чтения из необработанного потока. Количество возвращаемых байтов может быть меньше или больше запрошенного.

read(size=- 1, /)

Считывает и возвращает size байт или, если size не задан или отрицателен, до EOF или если вызов чтения блокируется в неблокирующем режиме.

read1(size=- 1, /)

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

Изменено в версии 3.7: Аргумент size теперь является необязательным.

class io.BufferedWriter(raw, buffer_size=DEFAULT_BUFFER_SIZE)

Буферизованный двоичный поток, обеспечивающий высокоуровневый доступ к необработанному двоичному потоку RawIOBase с возможностью записи и поиска. Он наследует BufferedIOBase.

При записи в этот объект данные обычно помещаются во внутренний буфер. Буфер будет записан в базовый объект RawIOBase при различных условиях, включая:

  • когда буфер становится слишком мал для всех ожидающих данных;

  • когда вызывается flush();

  • когда запрашивается seek() (для объектов BufferedRandom);

  • когда объект BufferedWriter закрывается или уничтожается.

Конструктор создает BufferedWriter для заданного записываемого raw потока. Если размер буфера не задан, по умолчанию используется значение DEFAULT_BUFFER_SIZE.

BufferedWriter предоставляет или переопределяет эти методы в дополнение к методам из BufferedIOBase и IOBase:

flush()

Выдавать байты, хранящиеся в буфере, в необработанный поток. Если необработанный поток блокируется, должен быть вызван сигнал BlockingIOError.

write(b, /)

Запишите bytes-like object, b, и верните количество записанных байт. В неблокирующем режиме, если буфер должен быть выписан, но необработанный поток блокируется, возникает ошибка BlockingIOError.

class io.BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)

Буферизованный двоичный поток, обеспечивающий высокоуровневый доступ к необработанному двоичному потоку с возможностью поиска RawIOBase. Он наследует BufferedReader и BufferedWriter.

Конструктор создает читателя и писателя для сырого потока с возможностью поиска, указанного в первом аргументе. Если размер buffer_size опущен, то по умолчанию он равен DEFAULT_BUFFER_SIZE.

BufferedRandom способен на все, на что способны BufferedReader или BufferedWriter. Кроме того, seek() и tell() гарантированно будут реализованы.

class io.BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE, /)

Буферизованный двоичный поток, обеспечивающий высокоуровневый доступ к двум необработанным двоичным потокам без поиска RawIOBase - один доступен для чтения, другой для записи. Он наследует BufferedIOBase.

reader и writer - это объекты RawIOBase, доступные для чтения и записи соответственно. Если параметр buffer_size опущен, то по умолчанию он равен DEFAULT_BUFFER_SIZE.

BufferedRWPair реализует все методы BufferedIOBase, кроме detach(), который вызывает UnsupportedOperation.

Предупреждение

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

Ввод/вывод текста

class io.TextIOBase

Базовый класс для текстовых потоков. Этот класс предоставляет символьный и строковый интерфейс для ввода/вывода потоков. Он наследует IOBase.

TextIOBase предоставляет или переопределяет эти атрибуты и методы данных в дополнение к атрибутам и методам из IOBase:

encoding

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

errors

Настройка ошибки декодера или кодера.

newlines

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

buffer

Базовый двоичный буфер (экземпляр BufferedIOBase), с которым работает TextIOBase. Это не является частью API TextIOBase и может отсутствовать в некоторых реализациях.

detach()

Отделите основной двоичный буфер от TextIOBase и верните его.

После отсоединения базового буфера TextIOBase находится в непригодном для использования состоянии.

Некоторые реализации TextIOBase, например StringIO, могут не иметь понятия базового буфера, и вызов этого метода вызовет ошибку UnsupportedOperation.

Добавлено в версии 3.1.

read(size=- 1, /)

Считывает и возвращает не более size символов из потока в виде одного str. Если size отрицателен или None, чтение происходит до EOF.

readline(size=- 1, /)

Считывать до новой строки или EOF и возвращать единственное значение str. Если поток уже находится в EOF, возвращается пустая строка.

Если указан size, будет считано не более size символов.

seek(offset, whence=SEEK_SET, /)

Изменение позиции потока на заданное смещение. Поведение зависит от параметра whence. Значение по умолчанию для whence равно SEEK_SET.

  • SEEK_SET или 0: поиск от начала потока (по умолчанию); offset должно быть либо числом, возвращаемым TextIOBase.tell(), либо нулем. Любое другое значение offset приводит к неопределенному поведению.

  • SEEK_CUR или 1: «поиск» до текущей позиции; offset должно быть равно нулю, что является запретом на выполнение операции (все другие значения не поддерживаются).

  • SEEK_END или 2: поиск до конца потока; offset должно быть равно нулю (все другие значения не поддерживаются).

Возвращает новую абсолютную позицию в виде непрозрачного числа.

Добавлено в версии 3.1: Константы SEEK_*.

tell()

Возвращает текущую позицию потока в виде непрозрачного числа. Это число обычно не представляет собой количество байтов в базовом двоичном хранилище.

write(s, /)

Записать строку s в поток и вернуть количество записанных символов.

class io.TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False, write_through=False)

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

encoding задает имя кодировки, с которой будет декодирован или закодирован поток. По умолчанию это значение равно locale.getpreferredencoding(False). encoding="locale" можно использовать для явного указания кодировки текущей локали. Дополнительную информацию смотрите в Кодирование текста.

errors - необязательная строка, определяющая, как будут обрабатываться ошибки кодирования и декодирования. Передайте 'strict', чтобы вызвать исключение ValueError при ошибке кодирования (по умолчанию None имеет тот же эффект), или передайте 'ignore', чтобы игнорировать ошибки. (Обратите внимание, что игнорирование ошибок кодирования может привести к потере данных). 'replace' вызывает вставку маркера замены (например, '?') в тех местах, где имеются неправильно сформированные данные. 'backslashreplace' вызывает замену неправильных данных на обратную косую черту. При записи можно использовать 'xmlcharrefreplace' (заменить на соответствующую ссылку на символ XML) или 'namereplace' (заменить на экранирующую последовательность \N{...}). Любое другое имя обработки ошибок, которое было зарегистрировано с помощью codecs.register_error(), также является действительным.

newline управляет тем, как обрабатываются окончания строк. Она может быть None, '', '\n', '\r' и '\r\n'. Он работает следующим образом:

  • При чтении ввода из потока, если newline равен None, включается режим universal newlines. Строки во входных данных могут заканчиваться на '\n', '\r' или '\r\n', и они преобразуются в '\n' перед возвратом вызывающей стороне. Если newline имеет значение '', включается режим универсальных новых строк, но окончания строк возвращаются вызывающей стороне непереведенными. Если newline имеет любое из других допустимых значений, входные строки завершаются только заданной строкой, а окончание строки возвращается вызывающей стороне в непереведенном виде.

  • При записи вывода в поток, если newline имеет значение None, все записанные символы '\n' переводятся в системный разделитель строк по умолчанию os.linesep. Если newline равен '' или '\n', перевод не выполняется. Если newline имеет любое из других допустимых значений, все записанные символы '\n' переводятся в заданную строку.

Если line_buffering равен True, то flush() подразумевается, когда вызов записи содержит символ новой строки или возврат каретки.

Если write_through равно True, вызовы write() гарантированно не буферизируются: любые данные, записанные на объект TextIOWrapper, немедленно обрабатываются в его базовый двоичный буфер.

Изменено в версии 3.3: Добавлен аргумент write_through.

Изменено в версии 3.3: Кодировка по умолчанию теперь locale.getpreferredencoding(False) вместо locale.getpreferredencoding(). Не меняйте временно кодировку локали с помощью locale.setlocale(), используйте текущую кодировку локали вместо предпочитаемой пользователем кодировки.

Изменено в версии 3.10: Аргумент encoding теперь поддерживает имя фиктивной кодировки "locale".

TextIOWrapper предоставляет эти атрибуты и методы данных в дополнение к атрибутам и методам из TextIOBase и IOBase:

line_buffering

Включена ли буферизация линии.

write_through

Передаются ли записи сразу в базовый двоичный буфер.

Добавлено в версии 3.7.

reconfigure(*[, encoding][, errors][, newline][, line_buffering][, write_through])

Переконфигурируйте этот текстовый поток, используя новые настройки для encoding, errors, newline, line_buffering и write_through.

Не указанные параметры сохраняют текущие настройки, за исключением errors='strict', который используется, когда encoding указан, но errors не указан.

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

Этот метод выполняет неявную очистку потока перед установкой новых параметров.

Добавлено в версии 3.7.

class io.StringIO(initial_value='', newline='\n')

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

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

Начальное значение буфера можно задать, указав initial_value. Если перевод новой строки включен, новые строки будут кодироваться как write(). Поток позиционируется в начало буфера.

Аргумент newline работает аналогично аргументу TextIOWrapper, за исключением того, что при записи вывода в поток, если newline равен None, новые строки записываются как \n на всех платформах.

StringIO предоставляет этот метод в дополнение к методам из TextIOBase и IOBase:

getvalue()

Возвращает str, содержащий все содержимое буфера. Новые строки декодируются как read(), хотя позиция потока не изменяется.

Пример использования:

import io

output = io.StringIO()
output.write('First line.\n')
print('Second line.', file=output)

# Retrieve file contents -- this will be
# 'First line.\nSecond line.\n'
contents = output.getvalue()

# Close object and discard memory buffer --
# .getvalue() will now raise an exception.
output.close()
class io.IncrementalNewlineDecoder

Вспомогательный кодек, который декодирует новые строки для режима universal newlines. Он наследует codecs.IncrementalDecoder.

Производительность

В этом разделе обсуждается производительность предоставленных конкретных реализаций ввода-вывода.

Двоичный ввод/вывод

Читая и записывая только большие куски данных, даже если пользователь запрашивает один байт, буферизованный ввод-вывод скрывает любую неэффективность вызова и выполнения небуферизованных процедур ввода-вывода операционной системы. Выигрыш зависит от ОС и типа выполняемого ввода-вывода. Например, в некоторых современных ОС, таких как Linux, небуферизованный дисковый ввод-вывод может быть таким же быстрым, как буферизованный ввод-вывод. В итоге, однако, буферизованный ввод-вывод обеспечивает предсказуемую производительность независимо от платформы и базового устройства. Поэтому почти всегда предпочтительнее использовать буферизованный ввод-вывод, а не небуферизованный ввод-вывод для двоичных данных.

Ввод/вывод текста

Ввод/вывод текста через двоичное хранилище (например, файл) значительно медленнее, чем ввод/вывод двоичных данных через то же хранилище, поскольку требует преобразования между юникодом и двоичными данными с помощью символьного кодека. Это может стать заметным при работе с огромными объемами текстовых данных, например, большими файлами журналов. Кроме того, TextIOWrapper.tell() и TextIOWrapper.seek() работают довольно медленно из-за используемого алгоритма реконструкции.

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

Многопоточность

Объекты FileIO являются потокобезопасными в той степени, в какой потокобезопасны и вызовы операционной системы (например, read(2) под Unix), которые они оборачивают.

Двоичные буферизованные объекты (экземпляры BufferedReader, BufferedWriter, BufferedRandom и BufferedRWPair) защищают свои внутренние структуры с помощью блокировки; поэтому их безопасно вызывать из нескольких потоков одновременно.

Объекты TextIOWrapper не являются потокобезопасными.

Reentrancy

Двоичные буферизованные объекты (экземпляры BufferedReader, BufferedWriter, BufferedRandom и BufferedRWPair) не являются реентерабельными. Хотя реентерабельные вызовы не происходят в обычных ситуациях, они могут возникнуть при выполнении ввода/вывода в обработчике signal. Если поток пытается повторно войти в буферизованный объект, к которому он уже обращается, то возникает ошибка RuntimeError. Обратите внимание, что это не запрещает другому потоку войти в буферизованный объект.

Вышесказанное неявно распространяется на текстовые файлы, поскольку функция open() будет оборачивать буферизованный объект внутри TextIOWrapper. Это включает стандартные потоки и, следовательно, влияет и на встроенную функцию print().

Вернуться на верх