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¶
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ů,
0na konci streamu, neboNone, 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 hodnotuerrno.
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í
bytespro binární streamy astrpro 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.
- close() None¶
Zavře stream a uvolní všechny podkladové prostředky. Operace na zavřeném streamu vyvolávají
OSError(neboValueErroru 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áOSErroru streamu, ve kterém nelze nastavovat pozici.
- 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žewith 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_objamp_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 jakomachine.UARTk implementaci vlastníchread/write– žádná standardní třída streamu je však neváže jako z Pythonu volatelné metodyread1/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ů.
- 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.
- close() None¶
Zavře stream a uvolní podkladový buffer. Další operace na zavřeném streamu vyvolávají
ValueError.
- class io.StringIO(alloc_size: int)
Vytvoří prázdný objekt
StringIOpř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ů.
- 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ů.
- 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.
- close() None¶
Zavře stream a uvolní podkladový buffer. Další operace na zavřeném streamu vyvolávají
ValueError.
- class io.BytesIO(alloc_size: int)
Vytvoří prázdný objekt
BytesIOpř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ů.
- 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.