io — in-/utströmmar¶
Denna modul innehåller ytterligare typer av stream-objekt (fil-liknande) samt hjälpfunktioner. Den exponerar den inbyggda open() tillsammans med text- och binärbuffertar i minnet (StringIO, BytesIO) som implementerar det vanliga ström-gränssnittet read/write/seek.
Begreppsmässig hierarki¶
Skillnad mot CPython
Den begreppsmässiga hierarkin av basklasser för strömmar är förenklad i MicroPython, vilket beskrivs i detta avsnitt.
(Abstrakta) basklasser för strömmar, som ligger till grund för beteendet hos alla konkreta klasser, följer i CPython ett antal dikotomier (parvisa klassificeringar). I MicroPython är de något förenklade och gjorda implicita för att uppnå högre effektivitet och spara resurser.
En viktig dikotomi i CPython är obuffrade kontra buffrade strömmar. I MicroPython är för närvarande alla strömmar obuffrade. Detta beror på att alla moderna operativsystem, och även många RTOS:er och filsystemsdrivrutiner, redan utför buffring på sin sida. Att lägga till ytterligare ett buffringslager är kontraproduktivt (ett problem känt som ”bufferbloat”) och tar dyrbart minne. Observera att det fortfarande finns fall där buffring kan vara användbar, så vi kan komma att införa valfritt buffringsstöd vid ett senare tillfälle.
Men i CPython är en annan viktig dikotomi knuten till ”buffrethet” - nämligen huruvida en ström kan drabbas av korta läsningar/skrivningar eller inte. En kort läsning är när en användare exempelvis ber om 10 byte från en ström, men får färre, och på motsvarande sätt för skrivningar. I CPython är obuffrade strömmar automatiskt mottagliga för korta operationer, medan buffrade garanteras mot dem. Frånvaron av korta läsningar/skrivningar är en viktig egenskap, eftersom den gör det möjligt att utveckla mer koncisa och effektiva program - något som är högst önskvärt för MicroPython. Så även om MicroPython inte stöder buffrade strömmar, tillhandahåller den ändå strömmar utan korta operationer. Huruvida det förekommer korta operationer eller inte beror på varje enskild klass behov, men utvecklare uppmanas starkt att föredra beteendet utan korta operationer av de skäl som anges ovan. Till exempel garanteras MicroPython-socketar att undvika korta läsningar/skrivningar. Faktum är att det för närvarande inte finns något exempel på en strömklass med korta operationer i kärnan, och en sådan klass skulle vara specifik för viss hårdvara.
Beteendet utan korta operationer blir besvärligt när det gäller icke-blockerande strömmar, där blockerande kontra icke-blockerande beteende är ytterligare en CPython-dikotomi, som stöds fullt ut av MicroPython. Icke-blockerande strömmar väntar aldrig på att data ska anlända eller skrivas - de läser/skriver vad som är möjligt, eller signalerar avsaknad av data (eller förmåga att skriva data). Detta står tydligt i konflikt med policyn ”inga korta operationer”, och mycket riktigt är fallet med icke-blockerande buffrade (och därmed korta-operationsfria) strömmar invecklat i CPython - på vissa ställen är en sådan kombination förbjuden, på vissa är den odefinierad eller helt enkelt odokumenterad, och i vissa fall ger den utförliga undantag. Saken är mycket enklare i MicroPython: icke-blockerande strömmar är viktiga för effektiva asynkrona operationer, så denna egenskap väger tyngre än egenskapen ”inga korta operationer”. Så även om blockerande strömmar undviker korta läsningar/skrivningar när det är möjligt (det enda fallet där en kort läsning kan ske är om slutet på filen nås, eller vid fel (men fel returnerar inte korta data utan ger undantag)), kan icke-blockerande strömmar producera korta data för att undvika att blockera operationen.
Den sista dikotomin är binära kontra textströmmar. MicroPython stöder naturligtvis dessa, men medan textströmmar i CPython i sig är buffrade, är de inte det i MicroPython. (Detta är förvisso ett av de fall för vilka vi kan komma att införa buffringsstöd.)
Observera att MicroPython av effektivitetsskäl inte tillhandahåller abstrakta basklasser som motsvarar hierarkin ovan, och det går inte att implementera, eller subklassa, en strömklass i ren Python.
Funktioner¶
Klasser¶
- class io.IOBase¶
Basklass för ström-objekt (”fil-liknande”). Konkreta subklasser implementerar de lågnivå-I/O-metoder som beskrivs nedan (
readinto,write,ioctl); körmiljön bygger det högre ströms-protokollet (read,readline,readlines,close, iteration) ovanpå dem, så varje strömsinstans stöder dessa metoder även när subklassen inte definierar dem.Implementationsmetoder (åsidosätt dessa i en subklass):
- readinto(buf: bytearray) int | None¶
Läs byte in i den skrivbara bufferten buf. Returnerar antalet lästa byte,
0vid slutet av strömmen, ellerNoneom inga data är tillgängliga just nu (för en icke-blockerande ström).
- write(buf: bytes) int | None¶
Skriv byten i buf. Returnerar antalet skrivna byte, eller
Noneom skrivningen inte kan utföras just nu (för en icke-blockerande ström).
- ioctl(request: int, arg: int) int¶
Styr den underliggande strömmen/enheten. request är en av begäranskoderna
MP_STREAM_*. Returnerar ett icke-negativt värde vid framgång, eller ett negativterrno-värde vid fel.
Ströms-protokollsmetoder (tillgängliga på varje strömsinstans):
- read(size: int = -1)¶
Läs och returnera upp till size byte (eller tecken, i textläge). Om size utelämnas eller är negativt, läs till slutet av strömmen. Returnerar
bytesför binära strömmar ochstrför textströmmar; ett tomt resultat indikerar slutet av strömmen.
- readline(size: int = -1)¶
Läs och returnera en rad, inklusive det avslutande radslutstecknet om ett sådant finns. Om size anges läses högst size byte (eller tecken). Returnerar ett tomt
bytes/strvid slutet av strömmen.
- readlines() list¶
Läs till slutet av strömmen och returnera en
listmed rader, var och en med sitt avslutande radslutstecken.
- close() None¶
Stäng strömmen och frigör eventuella underliggande resurser. Operationer på en stängd ström ger
OSError(ellerValueErrorför strömmar i minnet).
- seek(offset: int, whence: int = 0) int¶
Ändra den aktuella strömpositionen till offset byte relativt whence (
0= strömmens början,1= aktuell position,2= strömmens slut). Returnerar den nya absoluta positionen. GerOSErrorpå en ström som inte är sökbar.
- flush() None¶
Töm eventuella skrivbuffertar och skicka väntande data till den underliggande enheten eller filen. En icke-operation på strömmar som inte buffrar.
Att iterera över en ström direkt ger en rad per iteration – vilket motsvarar att anropa
readline()i en loop tills den tomma raden returneras som signal för slutet av strömmen. En ström stöder också context manager-protokollet, såwith open(...) as f:stänger strömmen automatiskt.Anteckning
MicroPythons strömmodul exponerar även ”1”-suffixerade C-hjälpfunktioner
mp_stream_read1_obj,mp_stream_readinto1_objochmp_stream_write1_objsom utför ett enda underliggande I/O-anrop istället för att loopa tills begäran är helt uppfylld. De används internt av klasser sommachine.UARTför att implementera sina egnaread/write– men ingen standardströmklass binder dem som Python-anropbara metoderread1/readinto1/write1.
- class io.StringIO(string: str = '')¶
Fil-liknande objekt i minnet för in-/utmatning i textläge (liknande en vanlig fil öppnad med modifieraren ”t”). Initialt innehåll kan anges med parametern string (som ska vara en vanlig sträng). Instanser stöder också context manager-protokollet (användbart i en
with-sats).- read(size: int = -1) str¶
Läs och returnera upp till size tecken. Om size utelämnas eller är negativt, läs och returnera allt återstående innehåll.
- readinto(buf: bytearray) int¶
Läs in i den förallokerade, skrivbara bufferten buf och returnera antalet lästa byte.
- seek(offset: int, whence: int = 0) int¶
Ändra strömpositionen till offset relativt whence (
0= början,1= aktuell,2= slut) och returnera den nya absoluta positionen.
- close() None¶
Stäng strömmen och frigör den underliggande bufferten. Vidare operationer på en stängd ström ger
ValueError.
- class io.StringIO(alloc_size: int)
Skapa ett tomt
StringIO-objekt förallokerat att rymma upp till alloc_size byte, så att skrivning av upp till så många byte inte omallokerar bufferten (vilket undviker en situation med slut på minne eller minnesfragmentering). Denna konstruktor är en MicroPython-utökning som endast rekommenderas för specialfall och systemnivåbibliotek, inte för slutanvändarapplikationer.Skillnad mot CPython
Denna konstruktor är en MicroPython-utökning.
- read(size: int = -1) str
Läs och returnera upp till size tecken. Om size utelämnas eller är negativt, läs och returnera allt återstående innehåll.
- readinto(buf: bytearray) int
Läs in i den förallokerade, skrivbara bufferten buf och returnera antalet lästa byte.
- seek(offset: int, whence: int = 0) int
Ändra strömpositionen till offset relativt whence (
0= början,1= aktuell,2= slut) och returnera den nya absoluta positionen.
- tell() int
Returnerar den aktuella strömpositionen.
- flush() None
Töm skrivbuffertarna. Detta är en icke-operation för en ström i minnet.
- close() None
Stäng strömmen och frigör den underliggande bufferten. Vidare operationer på en stängd ström ger
ValueError.
- getvalue() str
Returnerar det aktuella innehållet i den underliggande bufferten.
- class io.BytesIO(string: bytes = b'')¶
Fil-liknande objekt i minnet för in-/utmatning i binärläge (liknande en vanlig fil öppnad med modifieraren ”b”). Initialt innehåll kan anges med parametern string (som ska vara ett bytes-objekt). Instanser stöder också context manager-protokollet (användbart i en
with-sats).- read(size: int = -1) bytes¶
Läs och returnera upp till size byte. Om size utelämnas eller är negativt, läs och returnera allt återstående innehåll.
- readinto(buf: bytearray) int¶
Läs in i den förallokerade, skrivbara bufferten buf och returnera antalet lästa byte.
- seek(offset: int, whence: int = 0) int¶
Ändra strömpositionen till offset relativt whence (
0= början,1= aktuell,2= slut) och returnera den nya absoluta positionen.
- close() None¶
Stäng strömmen och frigör den underliggande bufferten. Vidare operationer på en stängd ström ger
ValueError.
- class io.BytesIO(alloc_size: int)
Skapa ett tomt
BytesIO-objekt förallokerat att rymma upp till alloc_size byte, så att skrivning av upp till så många byte inte omallokerar bufferten (vilket undviker en situation med slut på minne eller minnesfragmentering). Denna konstruktor är en MicroPython-utökning som endast rekommenderas för specialfall och systemnivåbibliotek, inte för slutanvändarapplikationer.Skillnad mot CPython
Denna konstruktor är en MicroPython-utökning.
- read(size: int = -1) bytes
Läs och returnera upp till size byte. Om size utelämnas eller är negativt, läs och returnera allt återstående innehåll.
- readinto(buf: bytearray) int
Läs in i den förallokerade, skrivbara bufferten buf och returnera antalet lästa byte.
- seek(offset: int, whence: int = 0) int
Ändra strömpositionen till offset relativt whence (
0= början,1= aktuell,2= slut) och returnera den nya absoluta positionen.
- tell() int
Returnerar den aktuella strömpositionen.
- flush() None
Töm skrivbuffertarna. Detta är en icke-operation för en ström i minnet.
- close() None
Stäng strömmen och frigör den underliggande bufferten. Vidare operationer på en stängd ström ger
ValueError.
- getvalue() bytes
Returnerar det aktuella innehållet i den underliggande bufferten.