io — vstupní/výstupní streamy

Tento modul obsahuje další typy objektů stream (souborového typu) a pomocné funkce. Zpřístupňuje vestavěnou funkci open() spolu s textovými a binárními buffery v paměti (StringIO, BytesIO), které implementují standardní stream rozhraní read/write/seek.

Koncepční hierarchie

Rozdíl oproti CPythonu

Koncepční hierarchie základních tříd streamů je v MicroPythonu zjednodušena, jak je popsáno v této sekci.

(Abstraktní) základní třídy streamů, které slouží jako základ chování všech konkrétních tříd, se v CPythonu řídí několika dichotomiemi (párovými klasifikacemi). V MicroPythonu jsou poněkud zjednodušeny a implicitní, aby se dosáhlo vyšší efektivity a ušetřily prostředky.

Důležitou dichotomií v CPythonu je rozdíl mezi nebufferovanými a bufferovanými streamy. V MicroPythonu jsou aktuálně všechny streamy nebufferované. Je to proto, že všechny moderní operační systémy, a dokonce i mnoho RTOS a ovladačů souborových systémů, již provádějí bufferování na své straně. Přidání další vrstvy bufferování je kontraproduktivní (problém známý jako „bufferbloat“) a zabírá cennou paměť. Všimněte si, že stále existují případy, kdy může být bufferování užitečné, takže můžeme volitelnou podporu bufferování zavést později.

V CPythonu je však s „bufferovaností“ spjata další důležitá dichotomie – zda u streamu může docházet ke krátkým čtením/zápisům, nebo ne. Ke krátkému čtení dochází, když uživatel požaduje např. 10 bajtů ze streamu, ale dostane méně; podobně to platí pro zápisy. V CPythonu jsou nebufferované streamy automaticky náchylné ke krátkým operacím, zatímco bufferované je proti nim garantují. Absence krátkých čtení/zápisů je důležitá vlastnost, protože umožňuje vyvíjet stručnější a efektivnější programy – což je pro MicroPython velmi žádoucí. Takže ačkoli MicroPython nepodporuje bufferované streamy, přesto poskytuje streamy bez krátkých operací. Zda ke krátkým operacím dojde, nebo ne, závisí na potřebách každé konkrétní třídy, ale vývojářům se důrazně doporučuje upřednostňovat chování bez krátkých operací z výše uvedených důvodů. Například u soketů v MicroPythonu je zaručeno, že se vyhnou krátkým čtením/zápisům. Ve skutečnosti v současné době v jádře neexistuje žádný příklad třídy streamu s krátkými operacemi a taková třída by byla specifická pro konkrétní hardware.

Chování bez krátkých operací se stává složitým v případě neblokujících streamů, přičemž blokující vs. neblokující chování je další dichotomií CPythonu, plně podporovanou MicroPythonem. Neblokující streamy nikdy nečekají na příchod dat ani na jejich zápis – čtou/zapisují, co je možné, nebo signalizují nedostatek dat (nebo schopnosti data zapsat). To je jednoznačně v rozporu s pravidlem „bez krátkých operací“, a skutečně, případ neblokujících bufferovaných (a tedy bez krátkých operací) streamů je v CPythonu spletitý – na některých místech je taková kombinace zakázána, jinde je nedefinovaná nebo prostě nezdokumentovaná a v některých případech vyvolává výmluvné výjimky. V MicroPythonu je tato záležitost mnohem jednodušší: neblokující streamy jsou důležité pro efektivní asynchronní operace, takže tato vlastnost převáží nad vlastností „bez krátkých operací“. Takže zatímco blokující streamy se kdykoli to bude možné vyhnou krátkým čtením/zápisům (jediný případ krátkého čtení nastane, pokud je dosaženo konce souboru nebo v případě chyby (chyby však nevracejí krátká data, ale vyvolávají výjimky)), neblokující streamy mohou produkovat krátká data, aby se vyhnuly zablokování operace.

Poslední dichotomií je rozdíl mezi binárními a textovými streamy. MicroPython je samozřejmě podporuje, ale zatímco v CPythonu jsou textové streamy ze své podstaty bufferované, v MicroPythonu nejsou. (To je skutečně jeden z případů, kvůli kterým můžeme zavést podporu bufferování.)

Všimněte si, že kvůli efektivitě MicroPython neposkytuje abstraktní základní třídy odpovídající výše uvedené hierarchii a není možné implementovat ani odvodit třídu streamu v čistém Pythonu.

Funkce

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

Otevře soubor. Vestavěná funkce open() je aliasem této funkce. Parametr mode je vždy podporován; podpora dalších argumentů se může lišit.

Třídy

class io.IOBase

Základní třída pro objekty streamu (souborového typu). Konkrétní podtřídy implementují nízkoúrovňové I/O metody uvedené níže (readinto, write, ioctl); běhové prostředí nad nimi staví vyšší úroveň stream protokolu (read, readline, readlines, close, iterace), takže každá instance streamu tyto metody podporuje, i když je podtřída nedefinuje.

Implementační metody (přepište je v podtřídě):

readinto(buf: bytearray) int | None

Načte bajty do zapisovatelného bufferu buf. Vrátí počet načtených bajtů, 0 na konci streamu, nebo None, pokud právě nejsou data k dispozici (u neblokujícího streamu).

write(buf: bytes) int | None

Zapíše bajty z buf. Vrátí počet zapsaných bajtů, nebo None, pokud zápis nelze právě teď provést (u neblokujícího streamu).

ioctl(request: int, arg: int) int

Řídí podkladový stream/zařízení. request je jeden z kódů požadavků MP_STREAM_*. Při úspěchu vrátí nezápornou hodnotu, při chybě zápornou hodnotu errno.

Metody stream protokolu (dostupné na každé instanci streamu):

read(size: int = -1)

Načte a vrátí až size bajtů (nebo znaků v textovém režimu). Pokud je size vynechán nebo záporný, čte až do konce streamu. Vrací bytes pro binární streamy a str pro textové streamy; prázdný výsledek indikuje konec streamu.

readline(size: int = -1)

Načte a vrátí jeden řádek, včetně koncového znaku nového řádku, pokud je přítomen. Pokud je size zadáno, načte se nejvýše size bajtů (nebo znaků). Na konci streamu vrátí prázdné bytes / str.

readlines() list

Čte až do konce streamu a vrátí list řádků, každý s koncovým znakem nového řádku.

close() None

Zavře stream a uvolní všechny podkladové prostředky. Operace na zavřeném streamu vyvolávají OSError (nebo ValueError u streamů v paměti).

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

Změní aktuální pozici ve streamu na offset bajtů relativně vůči whence (0 = začátek streamu, 1 = aktuální pozice, 2 = konec streamu). Vrátí novou absolutní pozici. Vyvolá OSError u streamu, ve kterém nelze nastavovat pozici.

tell() int

Vrátí aktuální absolutní pozici ve streamu. Ekvivalent seek(0, 1).

flush() None

Vyprázdní všechny zápisové buffery a odešle čekající data do podkladového zařízení nebo souboru. U streamů, které nebufferují, nemá žádný efekt.

Přímá iterace streamu vrací při každé iteraci jeden řádek – ekvivalent volání readline() ve smyčce, dokud se nevrátí sentinel prázdného řádku označující konec streamu. Stream také podporuje protokol context manageru, takže with open(...) as f: stream automaticky zavře.

Poznámka

Modul streamů v MicroPythonu také zpřístupňuje C pomocníky se sufixem „1“ mp_stream_read1_obj, mp_stream_readinto1_obj a mp_stream_write1_obj, kteří provedou jediné podkladové I/O volání místo cyklení, dokud není požadavek plně splněn. Interně je používají třídy jako machine.UART k implementaci vlastních read / write – žádná standardní třída streamu je však neváže jako z Pythonu volatelné metody read1 / readinto1 / write1.

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

Objekt souborového typu v paměti pro vstup/výstup v textovém režimu (podobně jako běžný soubor otevřený s modifikátorem „t“). Počáteční obsah lze určit parametrem string (který by měl být běžný řetězec). Instance také podporují protokol context manageru (použitelné v příkazu with).

read(size: int = -1) str

Načte a vrátí až size znaků. Pokud je size vynechán nebo záporný, načte a vrátí veškerý zbývající obsah.

readline(size: int = -1) str

Načte a vrátí jeden řádek. Pokud je size zadáno, načte se nejvýše size znaků.

readinto(buf: bytearray) int

Načte data do předem alokovaného zapisovatelného bufferu buf a vrátí počet načtených bajtů.

write(s: str) int

Zapíše řetězec s a vrátí počet zapsaných znaků.

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

Změní pozici ve streamu na offset relativně vůči whence (0 = začátek, 1 = aktuální, 2 = konec) a vrátí novou absolutní pozici.

tell() int

Vrátí aktuální pozici ve streamu.

flush() None

Vyprázdní zápisové buffery. U streamu v paměti nemá žádný efekt.

close() None

Zavře stream a uvolní podkladový buffer. Další operace na zavřeném streamu vyvolávají ValueError.

getvalue() str

Vrátí aktuální obsah podkladového bufferu.

class io.StringIO(alloc_size: int)

Vytvoří prázdný objekt StringIO předem alokovaný tak, aby pojal až alloc_size bajtů, takže zápis až tohoto počtu bajtů buffer znovu nealokuje (čímž se vyhne nedostatku paměti nebo její fragmentaci). Tento konstruktor je rozšíření MicroPythonu doporučené pouze pro speciální případy a knihovny na systémové úrovni, nikoli pro koncové aplikace.

Rozdíl oproti CPythonu

Tento konstruktor je rozšíření MicroPythonu.

read(size: int = -1) str

Načte a vrátí až size znaků. Pokud je size vynechán nebo záporný, načte a vrátí veškerý zbývající obsah.

readline(size: int = -1) str

Načte a vrátí jeden řádek. Pokud je size zadáno, načte se nejvýše size znaků.

readinto(buf: bytearray) int

Načte data do předem alokovaného zapisovatelného bufferu buf a vrátí počet načtených bajtů.

write(s: str) int

Zapíše řetězec s a vrátí počet zapsaných znaků.

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

Změní pozici ve streamu na offset relativně vůči whence (0 = začátek, 1 = aktuální, 2 = konec) a vrátí novou absolutní pozici.

tell() int

Vrátí aktuální pozici ve streamu.

flush() None

Vyprázdní zápisové buffery. U streamu v paměti nemá žádný efekt.

close() None

Zavře stream a uvolní podkladový buffer. Další operace na zavřeném streamu vyvolávají ValueError.

getvalue() str

Vrátí aktuální obsah podkladového bufferu.

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

Objekt souborového typu v paměti pro vstup/výstup v binárním režimu (podobně jako běžný soubor otevřený s modifikátorem „b“). Počáteční obsah lze určit parametrem string (který by měl být objekt bytes). Instance také podporují protokol context manageru (použitelné v příkazu with).

read(size: int = -1) bytes

Načte a vrátí až size bajtů. Pokud je size vynechán nebo záporný, načte a vrátí veškerý zbývající obsah.

readline(size: int = -1) bytes

Načte a vrátí jeden řádek. Pokud je size zadáno, načte se nejvýše size bajtů.

readinto(buf: bytearray) int

Načte data do předem alokovaného zapisovatelného bufferu buf a vrátí počet načtených bajtů.

write(b: bytes) int

Zapíše objekt typu bytes b a vrátí počet zapsaných bajtů.

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

Změní pozici ve streamu na offset relativně vůči whence (0 = začátek, 1 = aktuální, 2 = konec) a vrátí novou absolutní pozici.

tell() int

Vrátí aktuální pozici ve streamu.

flush() None

Vyprázdní zápisové buffery. U streamu v paměti nemá žádný efekt.

close() None

Zavře stream a uvolní podkladový buffer. Další operace na zavřeném streamu vyvolávají ValueError.

getvalue() bytes

Vrátí aktuální obsah podkladového bufferu.

class io.BytesIO(alloc_size: int)

Vytvoří prázdný objekt BytesIO předem alokovaný tak, aby pojal až alloc_size bajtů, takže zápis až tohoto počtu bajtů buffer znovu nealokuje (čímž se vyhne nedostatku paměti nebo její fragmentaci). Tento konstruktor je rozšíření MicroPythonu doporučené pouze pro speciální případy a knihovny na systémové úrovni, nikoli pro koncové aplikace.

Rozdíl oproti CPythonu

Tento konstruktor je rozšíření MicroPythonu.

read(size: int = -1) bytes

Načte a vrátí až size bajtů. Pokud je size vynechán nebo záporný, načte a vrátí veškerý zbývající obsah.

readline(size: int = -1) bytes

Načte a vrátí jeden řádek. Pokud je size zadáno, načte se nejvýše size bajtů.

readinto(buf: bytearray) int

Načte data do předem alokovaného zapisovatelného bufferu buf a vrátí počet načtených bajtů.

write(b: bytes) int

Zapíše objekt typu bytes b a vrátí počet zapsaných bajtů.

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

Změní pozici ve streamu na offset relativně vůči whence (0 = začátek, 1 = aktuální, 2 = konec) a vrátí novou absolutní pozici.

tell() int

Vrátí aktuální pozici ve streamu.

flush() None

Vyprázdní zápisové buffery. U streamu v paměti nemá žádný efekt.

close() None

Zavře stream a uvolní podkladový buffer. Další operace na zavřeném streamu vyvolávají ValueError.

getvalue() bytes

Vrátí aktuální obsah podkladového bufferu.