io — strumienie wejścia/wyjścia

Ten moduł zawiera dodatkowe typy obiektów stream (przypominających pliki) oraz funkcje pomocnicze. Udostępnia wbudowaną funkcję open(), a także tekstowe i binarne bufory w pamięci (StringIO, BytesIO), które implementują standardowy interfejs strumieni read/write/seek.

Hierarchia pojęciowa

Różnica względem CPythona

Hierarchia pojęciowa bazowych klas strumieni jest w MicroPython uproszczona, co opisano w tej sekcji.

(Abstrakcyjne) bazowe klasy strumieni, które stanowią fundament zachowania wszystkich klas konkretnych, w CPythonie podlegają kilku dychotomiom (klasyfikacjom parami). W MicroPython są one nieco uproszczone i ukryte, aby osiągnąć wyższą wydajność i oszczędzać zasoby.

Ważną dychotomią w CPythonie jest podział na strumienie buforowane i niebuforowane. W MicroPython wszystkie strumienie są obecnie niebuforowane. Wynika to z faktu, że wszystkie nowoczesne systemy operacyjne, a nawet wiele systemów RTOS i sterowników systemów plików, już wykonują buforowanie po swojej stronie. Dodawanie kolejnej warstwy buforowania jest nieproduktywne (problem znany jako „bufferbloat”) i zajmuje cenną pamięć. Należy zauważyć, że nadal istnieją przypadki, w których buforowanie może być przydatne, dlatego w przyszłości możemy wprowadzić opcjonalne wsparcie dla buforowania.

Jednak w CPythonie kolejna ważna dychotomia jest powiązana z „buforowaniem” - chodzi o to, czy strumień może powodować krótkie odczyty/zapisy, czy nie. Krótki odczyt ma miejsce, gdy użytkownik prosi np. o 10 bajtów ze strumienia, ale otrzymuje mniej; podobnie dla zapisów. W CPythonie strumienie niebuforowane są automatycznie podatne na krótkie operacje, natomiast buforowane są przed nimi chronione. Brak krótkich odczytów/zapisów jest ważną cechą, ponieważ pozwala tworzyć bardziej zwięzłe i wydajne programy - coś, co jest wysoce pożądane w MicroPython. Dlatego, choć MicroPython nie obsługuje strumieni buforowanych, nadal zapewnia strumienie bez krótkich operacji. To, czy wystąpią krótkie operacje, czy nie, zależy od potrzeb każdej konkretnej klasy, ale deweloperom zdecydowanie zaleca się preferowanie zachowania bez krótkich operacji z podanych wyżej powodów. Na przykład gniazda sieciowe MicroPython mają gwarancję unikania krótkich odczytów/zapisów. W rzeczywistości obecnie nie ma w rdzeniu przykładu klasy strumienia z krótkimi operacjami, a taka klasa byłaby specyficzna dla konkretnego sprzętu.

Zachowanie bez krótkich operacji staje się trudne w przypadku strumieni nieblokujących, przy czym zachowanie blokujące vs nieblokujące to kolejna dychotomia CPythona, w pełni obsługiwana przez MicroPython. Strumienie nieblokujące nigdy nie czekają na nadejście lub zapisanie danych - odczytują/zapisują tyle, ile to możliwe, lub sygnalizują brak danych (albo brak możliwości zapisu danych). Wyraźnie koliduje to z polityką „braku krótkich operacji” i rzeczywiście przypadek nieblokujących, buforowanych (a więc bez krótkich operacji) strumieni jest w CPythonie zawiły - w niektórych miejscach taka kombinacja jest zabroniona, w niektórych niezdefiniowana lub po prostu nieudokumentowana, a w niektórych przypadkach zgłasza rozwlekłe wyjątki. Sprawa jest znacznie prostsza w MicroPython: strumienie nieblokujące są ważne dla wydajnych operacji asynchronicznych, więc ta właściwość przeważa nad „brakiem krótkich operacji”. Dlatego, choć strumienie blokujące będą unikać krótkich odczytów/zapisów, kiedy tylko to możliwe (jedynym przypadkiem otrzymania krótkiego odczytu jest osiągnięcie końca pliku lub wystąpienie błędu (ale błędy nie zwracają krótkich danych, lecz zgłaszają wyjątki)), strumienie nieblokujące mogą zwracać krótkie dane, aby uniknąć zablokowania operacji.

Ostatnia dychotomia to strumienie binarne vs tekstowe. MicroPython oczywiście je obsługuje, ale o ile w CPythonie strumienie tekstowe są z natury buforowane, o tyle w MicroPython tak nie jest. (Rzeczywiście, to jeden z przypadków, dla których możemy wprowadzić wsparcie dla buforowania.)

Należy zauważyć, że ze względu na wydajność MicroPython nie udostępnia abstrakcyjnych klas bazowych odpowiadających powyższej hierarchii i nie jest możliwe zaimplementowanie ani odziedziczenie klasy strumienia w czystym Pythonie.

Funkcje

io.open(name: str, mode: str = 'r', **kwargs) Any

Otwiera plik. Wbudowana funkcja open() jest aliasem tej funkcji. Parametr mode jest zawsze obsługiwany; obsługa innych argumentów może się różnić.

Klasy

class io.IOBase

Klasa bazowa dla obiektów strumieni („przypominających pliki”). Konkretne podklasy implementują niskopoziomowe metody we/wy opisane poniżej (readinto, write, ioctl); środowisko uruchomieniowe buduje na ich podstawie wyższy poziom protokołu strumienia (read, readline, readlines, close, iterację), dzięki czemu każda instancja strumienia obsługuje te metody nawet wtedy, gdy podklasa ich nie definiuje.

Metody implementacyjne (przesłoń je w podklasie):

readinto(buf: bytearray) int | None

Odczytuje bajty do zapisywalnego bufora buf. Zwraca liczbę odczytanych bajtów, 0 na końcu strumienia lub None, jeśli żadne dane nie są obecnie dostępne (dla strumienia nieblokującego).

write(buf: bytes) int | None

Zapisuje bajty z buf. Zwraca liczbę zapisanych bajtów lub None, jeśli zapis nie może zostać teraz wykonany (dla strumienia nieblokującego).

ioctl(request: int, arg: int) int

Steruje bazowym strumieniem/urządzeniem. request to jeden z kodów żądań MP_STREAM_*. Zwraca wartość nieujemną w przypadku powodzenia lub ujemną wartość errno w przypadku błędu.

Metody protokołu strumienia (dostępne w każdej instancji strumienia):

read(size: int = -1)

Odczytuje i zwraca do size bajtów (lub znaków, w trybie tekstowym). Jeśli size jest pominięte lub ujemne, odczytuje do końca strumienia. Zwraca bytes dla strumieni binarnych i str dla strumieni tekstowych; pusty wynik oznacza koniec strumienia.

readline(size: int = -1)

Odczytuje i zwraca jeden wiersz, włącznie z końcowym znakiem nowej linii, jeśli jest obecny. Jeśli podano size, odczytywanych jest co najwyżej size bajtów (lub znaków). Zwraca pusty bytes / str na końcu strumienia.

readlines() list

Odczytuje do końca strumienia i zwraca list wierszy, każdy z końcowym znakiem nowej linii.

close() None

Zamyka strumień i zwalnia wszelkie bazowe zasoby. Operacje na zamkniętym strumieniu zgłaszają OSError (lub ValueError dla strumieni w pamięci).

seek(offset: int, whence: int = 0) int

Zmienia bieżącą pozycję w strumieniu na offset bajtów względem whence (0 = początek strumienia, 1 = bieżąca pozycja, 2 = koniec strumienia). Zwraca nową pozycję bezwzględną. Zgłasza OSError w przypadku strumienia, w którym nie można przemieszczać pozycji.

tell() int

Zwraca bieżącą pozycję bezwzględną w strumieniu. Równoważne seek(0, 1).

flush() None

Opróżnia wszelkie bufory zapisu, przesyłając oczekujące dane do bazowego urządzenia lub pliku. Brak operacji w przypadku strumieni, które nie buforują.

Bezpośrednia iteracja strumienia zwraca jeden wiersz na iterację – równoważne wywoływaniu readline() w pętli aż do zwrócenia wartownika końca strumienia w postaci pustego wiersza. Strumień obsługuje również protokół menedżera kontekstu, więc with open(...) as f: automatycznie zamyka strumień.

Informacja

Moduł strumieni MicroPython udostępnia także funkcje pomocnicze w języku C z przyrostkiem „1”: mp_stream_read1_obj, mp_stream_readinto1_obj i mp_stream_write1_obj, które wykonują pojedyncze bazowe wywołanie we/wy zamiast pętli aż do pełnego spełnienia żądania. Są one używane wewnętrznie przez klasy takie jak machine.UART do implementacji własnych read / write – ale żadna standardowa klasa strumienia nie wiąże ich jako wywoływalnych z Pythona metod read1 / readinto1 / write1.

class io.StringIO(string: str = '')

Obiekt w pamięci przypominający plik, do wejścia/wyjścia w trybie tekstowym (podobny do zwykłego pliku otwartego z modyfikatorem „t”). Początkową zawartość można podać za pomocą parametru string (który powinien być zwykłym łańcuchem znaków). Instancje obsługują również protokół menedżera kontekstu (można ich używać w instrukcji with).

read(size: int = -1) str

Odczytuje i zwraca do size znaków. Jeśli size jest pominięte lub ujemne, odczytuje i zwraca całą pozostałą zawartość.

readline(size: int = -1) str

Odczytuje i zwraca jeden wiersz. Jeśli podano size, odczytywanych jest co najwyżej size znaków.

readinto(buf: bytearray) int

Odczytuje do wstępnie zaalokowanego, zapisywalnego bufora buf i zwraca liczbę odczytanych bajtów.

write(s: str) int

Zapisuje łańcuch s i zwraca liczbę zapisanych znaków.

seek(offset: int, whence: int = 0) int

Zmienia pozycję w strumieniu na offset względem whence (0 = początek, 1 = bieżąca, 2 = koniec) i zwraca nową pozycję bezwzględną.

tell() int

Zwraca bieżącą pozycję w strumieniu.

flush() None

Opróżnia bufory zapisu. Dla strumienia w pamięci jest to operacja pusta.

close() None

Zamyka strumień i zwalnia bazowy bufor. Dalsze operacje na zamkniętym strumieniu zgłaszają ValueError.

getvalue() str

Zwraca bieżącą zawartość bazowego bufora.

class io.StringIO(alloc_size: int)

Tworzy pusty obiekt StringIO z wstępną alokacją na co najwyżej alloc_size bajtów, dzięki czemu zapisanie do tylu bajtów nie spowoduje ponownej alokacji bufora (unikając sytuacji braku pamięci lub fragmentacji pamięci). Ten konstruktor jest rozszerzeniem MicroPython zalecanym tylko w szczególnych przypadkach i dla bibliotek systemowych, a nie dla aplikacji użytkownika końcowego.

Różnica względem CPythona

Ten konstruktor jest rozszerzeniem MicroPython.

read(size: int = -1) str

Odczytuje i zwraca do size znaków. Jeśli size jest pominięte lub ujemne, odczytuje i zwraca całą pozostałą zawartość.

readline(size: int = -1) str

Odczytuje i zwraca jeden wiersz. Jeśli podano size, odczytywanych jest co najwyżej size znaków.

readinto(buf: bytearray) int

Odczytuje do wstępnie zaalokowanego, zapisywalnego bufora buf i zwraca liczbę odczytanych bajtów.

write(s: str) int

Zapisuje łańcuch s i zwraca liczbę zapisanych znaków.

seek(offset: int, whence: int = 0) int

Zmienia pozycję w strumieniu na offset względem whence (0 = początek, 1 = bieżąca, 2 = koniec) i zwraca nową pozycję bezwzględną.

tell() int

Zwraca bieżącą pozycję w strumieniu.

flush() None

Opróżnia bufory zapisu. Dla strumienia w pamięci jest to operacja pusta.

close() None

Zamyka strumień i zwalnia bazowy bufor. Dalsze operacje na zamkniętym strumieniu zgłaszają ValueError.

getvalue() str

Zwraca bieżącą zawartość bazowego bufora.

class io.BytesIO(string: bytes = b'')

Obiekt w pamięci przypominający plik, do wejścia/wyjścia w trybie binarnym (podobny do zwykłego pliku otwartego z modyfikatorem „b”). Początkową zawartość można podać za pomocą parametru string (który powinien być obiektem bytes). Instancje obsługują również protokół menedżera kontekstu (można ich używać w instrukcji with).

read(size: int = -1) bytes

Odczytuje i zwraca do size bajtów. Jeśli size jest pominięte lub ujemne, odczytuje i zwraca całą pozostałą zawartość.

readline(size: int = -1) bytes

Odczytuje i zwraca jeden wiersz. Jeśli podano size, odczytywanych jest co najwyżej size bajtów.

readinto(buf: bytearray) int

Odczytuje do wstępnie zaalokowanego, zapisywalnego bufora buf i zwraca liczbę odczytanych bajtów.

write(b: bytes) int

Zapisuje obiekt przypominający bajty b i zwraca liczbę zapisanych bajtów.

seek(offset: int, whence: int = 0) int

Zmienia pozycję w strumieniu na offset względem whence (0 = początek, 1 = bieżąca, 2 = koniec) i zwraca nową pozycję bezwzględną.

tell() int

Zwraca bieżącą pozycję w strumieniu.

flush() None

Opróżnia bufory zapisu. Dla strumienia w pamięci jest to operacja pusta.

close() None

Zamyka strumień i zwalnia bazowy bufor. Dalsze operacje na zamkniętym strumieniu zgłaszają ValueError.

getvalue() bytes

Zwraca bieżącą zawartość bazowego bufora.

class io.BytesIO(alloc_size: int)

Tworzy pusty obiekt BytesIO z wstępną alokacją na co najwyżej alloc_size bajtów, dzięki czemu zapisanie do tylu bajtów nie spowoduje ponownej alokacji bufora (unikając sytuacji braku pamięci lub fragmentacji pamięci). Ten konstruktor jest rozszerzeniem MicroPython zalecanym tylko w szczególnych przypadkach i dla bibliotek systemowych, a nie dla aplikacji użytkownika końcowego.

Różnica względem CPythona

Ten konstruktor jest rozszerzeniem MicroPython.

read(size: int = -1) bytes

Odczytuje i zwraca do size bajtów. Jeśli size jest pominięte lub ujemne, odczytuje i zwraca całą pozostałą zawartość.

readline(size: int = -1) bytes

Odczytuje i zwraca jeden wiersz. Jeśli podano size, odczytywanych jest co najwyżej size bajtów.

readinto(buf: bytearray) int

Odczytuje do wstępnie zaalokowanego, zapisywalnego bufora buf i zwraca liczbę odczytanych bajtów.

write(b: bytes) int

Zapisuje obiekt przypominający bajty b i zwraca liczbę zapisanych bajtów.

seek(offset: int, whence: int = 0) int

Zmienia pozycję w strumieniu na offset względem whence (0 = początek, 1 = bieżąca, 2 = koniec) i zwraca nową pozycję bezwzględną.

tell() int

Zwraca bieżącą pozycję w strumieniu.

flush() None

Opróżnia bufory zapisu. Dla strumienia w pamięci jest to operacja pusta.

close() None

Zamyka strumień i zwalnia bazowy bufor. Dalsze operacje na zamkniętym strumieniu zgłaszają ValueError.

getvalue() bytes

Zwraca bieżącą zawartość bazowego bufora.