MicroPython:Библиотеки/uio
Модуль uio – потоковые объекты, с которыми можно выполнять операции чтения/записи[1]
В этом модуле реализована часть функционала соответствующего модуля CPython. Более подробно читайте в документации к CPython о модуле io.
Этот модуль содержит дополнительные типы потоковых (файлообразных) объектов и вспомогательные функции.
Иерархия понятий
Примечание: В MicroPython иерархия понятий потоковых классов упрощена. Подробнее читайте дальше.
В CPyton базовые потоковые классы, служащие фундаментом для поведения всех конкретных классов, должны отвечать требованиям нескольких дихотомий (попарных классификаций). В MicroPython они в некоторой степени упрощены и сделаны неявными с целью повысить производительность и сэкономить ресурсы.
В CPython есть важная дихотомия «потоки без буферов vs потоки с буферами». В данный момент в MicroPython все потоки – безбуферные. Причина в том, что все современные ОС и даже многие RTOS и драйверы файловых систем уже выполняют буферизацию сами. Наличие дополнительной буферизации контрпродуктивно (эта проблема известна как «излишняя буферизация»), и она, к тому же, требует памяти, которой и так часто не хватает. Но помните, что есть ситуации, когда буферизация по-прежнему нужна, поэтому в будущем разработчики, возможно, добавят поддержку опциональной буферизации.
Но в CPython есть еще одна важная дихотомия, связанная с «буферностью» – это то, может ли поток подвергаться коротким операциям считывания/записи или нет. Короткое считывание – это когда пользователь запрашивает из потока, например, 10 байтов, но получает меньше. То же самое касается и короткой записи. В CPython безбуферные потоки автоматически разрешают короткие операции, а потоки с буферами – наоборот. Отсутствие коротких операций считывания/записи – это важная черта, т.к. позволяет разрабатывать более лаконичные и эффективные программы, что как раз ценится в MicroPython. Таким образом, MicroPython не поддерживает потоки с буферами, но по-прежнему поддерживает потоки без коротких операций. То, будут ли у класса короткие операции или нет, зависит от нужд этого класса, но разработчики их использовать не рекомендуют (по причинам, о которых было сказано выше). Например, сокеты в MicroPython будут гарантированно избегать коротких операций считывания/записи. В принципе, на данный момент в ядре MicroPython нет потокового класса с короткими операциями, поэтому такой класс возможен только в MicroPython-портах, где управление короткими операциями реализовано аппаратно.
Кроме того, ситуация с некороткими операциями может быть непростой в случае с неблокирующими потоками. Блокирующие/неблокирующие потоки – это еще одна дихотомия CPython, полностью поддерживаемая в MicroPython. Неблокирующие потоки никогда не ждут прибытия/записи данных – они просто считывают/записывают любые доступные данные или сигнализируют об их отсутствии (или невозможности их записать). Очевидно, что это конфликтует с механизмом некоротких операций, а в CPython ситуация с неблокирующими буферными (и добавьте сюда эти некороткие операции) потоками и вовсе запутана донельзя – в некоторых случаях эта комбинация запрещена, в некоторых не определена или даже не задокументирована, а в некоторых – выдает очень «многословные» исключения. В MicroPython со всем этим гораздо проще: неблокирующий поток важен для асинхронных операций, поэтому это свойство превалирует над потоком с некороткими операциями. То есть, если блокирующие потоки будут всеми силами избегать коротких операций считывания/записи (единственная ситуация, когда может возникнуть короткое считывание – это при достижении конца файла или в случае ошибки, но даже ошибки не возвращают короткие данные, а возбуждают исключения), то неблокирующие потоки могут генерировать короткие данные, чтобы избегать блокирования операций.
Последняя дихотомия – это двоичные/текстовые потоки. MicroPython, разумеется, поддерживает оба этих типа, но если в CPython текстовые потоки являются буферными по умолчанию, то в MicroPython – нет. Это как раз одна из причин, по которой MicroPython может понадобиться поддержка буферизации.
Учтите, что в целях эффективности в MicroPython нет абстрактных базовых классов, соответствующих иерархии выше (их невозможно реализовать), или подкласса для потоков, как в «чистом» Python.
Функции
- uio.open(name, mode='r', **kwargs) – открывает файл. У встроенной функции open() псевдонимная связь с этой функцией. Все порты, предоставляющие доступ к файловой системе, должны поддерживать параметр mode, но в других портах поддержки других аргументов может не быть.
Классы
- Класс uio.FileIO(...) – это тип файла, открываемый в двоичном режиме, например, при помощи open(name, "rb"). Этот класс не следует инстанцинировать напрямую.
- Класс uio.TextIOWrapper(...) – это тип файла, открываемый в текстовом режиме, например, при помощи open(name, "rt"). Этот класс не следует инстанцинировать напрямую.
- Классы uio.StringIO([string]) и uio.BytesIO([string]) – это файлоподобные объекты для операций ввода/вывода в памяти. StringIO используется для ввода/вывода в текстовом режиме (аналогично нормальному файлу, открытому с помощью модификатора «t»). BytesIO используется для ввода/вывода в двоичном режиме (аналогично нормальному файлу, открытому с идентификатором «b»). Изначальное содержимое файлоподобных объектов может быть задано при помощи параметра string (для StringIO это должна быть обычная строка, а для BytesIO – объект bytes). На этих объектах можно использовать все стандартные файловые методы вроде read(), write(), seek(), flush() и close(), и вдобавок также этот метод:
- getvalue() – считывает текущее содержимое буфера, содержащего данные.
- Классы uio.StringIO(alloc_size) и uio.BytesIO(alloc_size) – создают пустой объект StringIO/BytesIO, память для которого выделяется заранее, чтобы занять место, заданное в параметре alloc_size (в байтах). Это значит, что запись этого количества данных не приведет к новому выделению места под буфер, а следовательно – не приведет к нехватке или фрагментации памяти. Эти конструкторы созданы специально для MicroPython, и их рекомендуется использовать только в специальных классах и системных библиотеках, но не в приложениях для конечного пользователя.
Примечание: Эти конструкторы являются расширениями MicroPython (т.е. не входят в CPython).
<syntaxhighlight lang="python" enclose="div">