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' в строке mode:

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.getencoding()).

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

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

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

См.также

Режим Python UTF-8

Режим Python UTF-8 Mode можно использовать для изменения кодировки по умолчанию на UTF-8 из кодировки, специфичной для конкретной локали.

PEP 686

В Python 3.15 Режим Python UTF-8 будет использоваться по умолчанию.

ОптКодированиеПредупреждение

Added in version 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

Значение int, содержащее размер буфера по умолчанию, используемый классами буферизованного ввода-вывода модуля. open() использует размер blksize файла (полученный с помощью 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'). Переопределение поведения предназначено для дополнительной проверки или предварительной обработки файла.

Added in version 3.8.

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

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

Эта функция возвращает кодировку, если она не является None. В противном случае возвращается "locale" или "utf-8" в зависимости от UTF-8 Mode.

Эта функция выдает предупреждение EncodingWarning, если sys.flags.warn_default_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()

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

Дополнительные сведения см. в разделе Кодирование текста.

Added in version 3.10.

Изменено в версии 3.11: text_encoding() возвращает «utf-8», если включен режим UTF-8 и encoding равен None.

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, если они не поддерживают ту или иную операцию.

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

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

Азбука TextIOBase ABC расширяет 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. В этом примере файл будет закрыт после завершения набора операторов 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=os.SEEK_SET, /)

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

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

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

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

Added in version 3.1: Константы SEEK_*.

Added in version 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 в байтах, в зависимости от специфики базового сырого потока, особенно если он работает в неблокирующем режиме. 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. Это не является частью BufferedIOBase API и может отсутствовать в некоторых реализациях.

detach()

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

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

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

Added in version 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 возникает, если базовый сырой поток находится в неблокирующем режиме и в данный момент не имеет доступных данных.

Added in version 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.

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

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

Пользовательский открыватель можно использовать, передав вызываемый объект в качестве opener. Дескриптор файла, лежащий в основе объекта файла, можно получить, вызвав opener с (имя, флаги). 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 нельзя изменить в размерах или закрыть.

Added in version 3.2.

getvalue()

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

read1(size=-1, /)

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

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

readinto1(b, /)

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

Added in version 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.

Конструктор создает читателя и писателя для сырого потока с возможностью поиска, указанного в первом аргументе. Если размер буфера опущен, то по умолчанию он принимает значение 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. Это не является частью TextIOBase API и может отсутствовать в некоторых реализациях.

detach()

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

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

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

Added in version 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: поиск до конца потока; смещение должно быть равно нулю (все остальные значения не поддерживаются).

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

Added in version 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.getencoding(). 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

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

Added in version 3.7.

reconfigure(*, encoding=None, errors=None, newline=None, line_buffering=None, write_through=None)

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

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

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

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

Added in version 3.7.

Изменено в версии 3.11: Метод поддерживает опцию encoding="locale".

seek(cookie, whence=os.SEEK_SET, /)

Установите позицию потока. Верните новую позицию потока в виде int.

Поддерживаются четыре операции, представленные следующими комбинациями аргументов:

  • seek(0, SEEK_SET): Перемотка к началу потока.

  • seek(cookie, SEEK_SET): Восстановление предыдущей позиции; cookie должен быть числом, возвращенным tell().

  • seek(0, SEEK_END): Перемотка вперед до конца потока.

  • seek(0, SEEK_CUR): Оставить текущую позицию потока без изменений.

Любые другие комбинации аргументов недопустимы и могут вызвать исключения.

См.также

os.SEEK_SET, os.SEEK_CUR и os.SEEK_END.

tell()

Возвращает позицию потока в виде непрозрачного числа. Возвращаемое значение tell() можно передать на вход seek(), чтобы восстановить предыдущую позицию потока.

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

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

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

Начальное значение буфера можно задать, указав initial_value. Если включена трансляция новых строк, то новые строки будут кодироваться как write(). Поток позиционируется в начало буфера, что эмулирует открытие существующего файла в режиме w+, делая его готовым к немедленной записи с самого начала или к записи, которая перезапишет начальное значение. Чтобы эмулировать открытие файла в режиме a+, готового к добавлению, используйте команду f.seek(0, io.SEEK_END), чтобы переместить поток в конец буфера.

Аргумент 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, небуферизованный дисковый ввод-вывод может быть таким же быстрым, как и буферизованный ввод-вывод. Однако суть в том, что буферизованный ввод-вывод обеспечивает предсказуемую производительность независимо от платформы и устройства поддержки. Поэтому почти всегда предпочтительнее использовать буферизованный ввод/вывод, а не небуферизованный ввод/вывод для двоичных данных.

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

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

Однако StringIO является собственным контейнером юникода in-memory и будет работать с такой же скоростью, как и BytesIO.

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

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

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

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

Reentrancy

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

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