io — invoer-/uitvoerstromen¶
Deze module bevat aanvullende typen stream-objecten (bestandachtige objecten) en hulpfuncties. Hij stelt de ingebouwde open() beschikbaar, samen met tekst- en binaire buffers in het geheugen (StringIO, BytesIO) die de standaard read/write/seek-streaminterface implementeren.
Conceptuele hiërarchie¶
Verschil met CPython
De conceptuele hiërarchie van de basisstreamklassen is in MicroPython vereenvoudigd, zoals in deze sectie beschreven.
(Abstracte) basisstreamklassen, die als fundament dienen voor het gedrag van alle concrete klassen, houden zich in CPython aan enkele dichotomieën (paarsgewijze classificaties). In MicroPython zijn ze enigszins vereenvoudigd en impliciet gemaakt om een hogere efficiëntie te bereiken en bronnen te besparen.
Een belangrijke dichotomie in CPython is gebufferde versus ongebufferde streams. In MicroPython zijn alle streams momenteel ongebufferd. Dit komt doordat alle moderne besturingssystemen, en zelfs veel RTOS’en en bestandssysteemstuurprogramma’s, aan hun kant al buffering uitvoeren. Een extra bufferlaag toevoegen werkt averechts (een probleem dat bekendstaat als “bufferbloat”) en kost kostbaar geheugen. Merk op dat er nog steeds gevallen zijn waarin buffering nuttig kan zijn, dus mogelijk introduceren we later optionele bufferingondersteuning.
Maar in CPython is een andere belangrijke dichotomie gekoppeld aan “bufferedheid” - namelijk of een stream korte read-/write-bewerkingen kan ondervinden of niet. Een korte read is wanneer een gebruiker bijvoorbeeld 10 bytes uit een stream opvraagt, maar minder krijgt; voor writes geldt dit analoog. In CPython zijn ongebufferde streams automatisch vatbaar voor korte bewerkingen, terwijl gebufferde streams hiertegen gegarandeerd beschermd zijn. Het ontbreken van korte read-/write-bewerkingen is een belangrijke eigenschap, omdat het de ontwikkeling van beknoptere en efficiëntere programma’s mogelijk maakt - iets wat voor MicroPython zeer wenselijk is. Dus hoewel MicroPython geen gebufferde streams ondersteunt, biedt het toch streams zonder korte bewerkingen. Of er korte bewerkingen zullen zijn of niet, hangt af van de behoeften van elke specifieke klasse, maar ontwikkelaars wordt ten zeerste aangeraden om de voorkeur te geven aan gedrag zonder korte bewerkingen, om de hierboven genoemde redenen. MicroPython-sockets zijn bijvoorbeeld gegarandeerd vrij van korte read-/write-bewerkingen. Op dit moment is er feitelijk geen voorbeeld van een streamklasse met korte bewerkingen in de kern, en zo’n klasse zou specifiek zijn voor bepaalde hardware.
Het gedrag zonder korte bewerkingen wordt lastig in het geval van niet-blokkerende streams, waarbij blokkerend versus niet-blokkerend gedrag een andere CPython-dichotomie is, die volledig door MicroPython wordt ondersteund. Niet-blokkerende streams wachten nooit tot er gegevens binnenkomen of worden weggeschreven - ze lezen/schrijven wat mogelijk is, of signaleren een gebrek aan gegevens (of het onvermogen om gegevens te schrijven). Dit conflicteert uiteraard met het beleid van “geen korte bewerkingen”, en inderdaad is het geval van niet-blokkerende gebufferde (en dus geen korte bewerkingen) streams in CPython ingewikkeld - op sommige plaatsen is zo’n combinatie verboden, op sommige is het ongedefinieerd of gewoon niet gedocumenteerd, en in sommige gevallen leidt het tot uitvoerige uitzonderingen. De zaak is in MicroPython veel eenvoudiger: niet-blokkerende streams zijn belangrijk voor efficiënte asynchrone bewerkingen, dus deze eigenschap prevaleert boven die van “geen korte bewerkingen”. Dus hoewel blokkerende streams korte read-/write-bewerkingen zoveel mogelijk vermijden (het enige geval waarin een korte read optreedt, is als het einde van het bestand wordt bereikt, of bij een fout (maar fouten geven geen korte gegevens terug, maar werpen uitzonderingen)), kunnen niet-blokkerende streams korte gegevens produceren om de bewerking niet te blokkeren.
De laatste dichotomie is binaire versus tekststreams. MicroPython ondersteunt deze uiteraard, maar terwijl tekststreams in CPython inherent gebufferd zijn, zijn ze dat in MicroPython niet. (Dit is inderdaad een van de gevallen waarvoor we mogelijk bufferingondersteuning introduceren.)
Merk op dat MicroPython omwille van de efficiëntie geen abstracte basisklassen biedt die overeenkomen met de bovenstaande hiërarchie, en dat het niet mogelijk is om een streamklasse in puur Python te implementeren of er een subklasse van te maken.
Functies¶
Klassen¶
- class io.IOBase¶
Basisklasse voor stream-objecten (“bestandachtige” objecten). Concrete subklassen implementeren de onderstaande low-level I/O-methoden (
readinto,write,ioctl); de runtime bouwt daarbovenop het hogere streamprotocol (read,readline,readlines,close, iteratie), zodat elke streaminstantie die methoden ondersteunt, zelfs wanneer de subklasse ze niet definieert.Implementatiemethoden (overschrijf deze in een subklasse):
- readinto(buf: bytearray) int | None¶
Lees bytes in de beschrijfbare buffer buf. Geeft het aantal gelezen bytes terug,
0aan het einde van de stream, ofNoneals er op dit moment geen gegevens beschikbaar zijn (voor een niet-blokkerende stream).
- write(buf: bytes) int | None¶
Schrijf de bytes in buf. Geeft het aantal geschreven bytes terug, of
Noneals de write op dit moment niet kan worden uitgevoerd (voor een niet-blokkerende stream).
- ioctl(request: int, arg: int) int¶
Bestuur de onderliggende stream/het onderliggende apparaat. request is een van de
MP_STREAM_*-requestcodes. Geeft bij succes een niet-negatieve waarde terug, of bij een fout een negatieveerrno-waarde.
Streamprotocolmethoden (beschikbaar op elke streaminstantie):
- read(size: int = -1)¶
Lees en geef maximaal size bytes terug (of tekens, in tekstmodus). Als size wordt weggelaten of negatief is, wordt er gelezen tot het einde van de stream. Geeft
bytesterug voor binaire streams enstrvoor tekststreams; een leeg resultaat duidt op het einde van de stream.
- readline(size: int = -1)¶
Lees en geef één regel terug, inclusief het afsluitende newline-teken als dat aanwezig is. Als size wordt opgegeven, worden er maximaal size bytes (of tekens) gelezen. Geeft een lege
bytes/strterug aan het einde van de stream.
- readlines() list¶
Lees tot het einde van de stream en geef een
listmet regels terug, elk met hun afsluitende newline.
- close() None¶
Sluit de stream en geef alle onderliggende bronnen vrij. Bewerkingen op een gesloten stream werpen
OSError(ofValueErrorvoor streams in het geheugen).
- seek(offset: int, whence: int = 0) int¶
Wijzig de huidige streampositie naar offset bytes ten opzichte van whence (
0= begin van de stream,1= huidige positie,2= einde van de stream). Geeft de nieuwe absolute positie terug. WerptOSErrorop een stream die niet doorzoekbaar is.
- flush() None¶
Maak alle schrijfbuffers leeg en duw de openstaande gegevens naar het onderliggende apparaat of bestand. Een no-op op streams die niet bufferen.
Het rechtstreeks itereren over een stream levert per iteratie één regel op – equivalent aan het in een lus aanroepen van
readline()totdat de lege-regel-sentinel voor het einde van de stream wordt teruggegeven. Een stream ondersteunt ook het contextmanagerprotocol, zodatwith open(...) as f:de stream automatisch sluit.Notitie
De streammodule van MicroPython stelt ook met “1” gesuffixte C-helpers
mp_stream_read1_obj,mp_stream_readinto1_objenmp_stream_write1_objbeschikbaar, die één enkele onderliggende I/O-aanroep uitvoeren in plaats van te blijven herhalen tot het verzoek volledig is afgehandeld. Ze worden intern gebruikt door klassen zoalsmachine.UARTom hun eigenread/writete implementeren – maar geen enkele standaard streamklasse bindt ze als vanuit Python aanroepbareread1/readinto1/write1-methoden.
- class io.StringIO(string: str = '')¶
Bestandachtig object in het geheugen voor invoer/uitvoer in tekstmodus (vergelijkbaar met een normaal bestand dat is geopend met de “t”-modifier). De initiële inhoud kan worden opgegeven met de parameter string (die een normale string moet zijn). Instanties ondersteunen ook het contextmanagerprotocol (bruikbaar in een
with-statement).- read(size: int = -1) str¶
Lees en geef maximaal size tekens terug. Als size wordt weggelaten of negatief is, wordt alle resterende inhoud gelezen en teruggegeven.
- readline(size: int = -1) str¶
Lees en geef één regel terug. Als size wordt opgegeven, worden er maximaal size tekens gelezen.
- readinto(buf: bytearray) int¶
Lees in de vooraf toegewezen, beschrijfbare buffer buf en geef het aantal gelezen bytes terug.
- seek(offset: int, whence: int = 0) int¶
Wijzig de streampositie naar offset ten opzichte van whence (
0= begin,1= huidige,2= einde) en geef de nieuwe absolute positie terug.
- close() None¶
Sluit de stream en geef de onderliggende buffer vrij. Verdere bewerkingen op een gesloten stream werpen
ValueError.
- class io.StringIO(alloc_size: int)
Maak een leeg
StringIO-object dat vooraf is toegewezen om maximaal alloc_size bytes te bevatten, zodat het schrijven van maximaal dat aantal bytes de buffer niet opnieuw zal toewijzen (waardoor een out-of-memory-situatie of geheugenfragmentatie wordt vermeden). Deze constructor is een MicroPython-uitbreiding die alleen wordt aanbevolen voor speciale gevallen en bibliotheken op systeemniveau, niet voor eindgebruikerstoepassingen.Verschil met CPython
Deze constructor is een MicroPython-uitbreiding.
- read(size: int = -1) str
Lees en geef maximaal size tekens terug. Als size wordt weggelaten of negatief is, wordt alle resterende inhoud gelezen en teruggegeven.
- readline(size: int = -1) str
Lees en geef één regel terug. Als size wordt opgegeven, worden er maximaal size tekens gelezen.
- readinto(buf: bytearray) int
Lees in de vooraf toegewezen, beschrijfbare buffer buf en geef het aantal gelezen bytes terug.
- seek(offset: int, whence: int = 0) int
Wijzig de streampositie naar offset ten opzichte van whence (
0= begin,1= huidige,2= einde) en geef de nieuwe absolute positie terug.
- tell() int
Geeft de huidige streampositie terug.
- flush() None
Maak de schrijfbuffers leeg. Dit is een no-op voor een stream in het geheugen.
- close() None
Sluit de stream en geef de onderliggende buffer vrij. Verdere bewerkingen op een gesloten stream werpen
ValueError.
- getvalue() str
Geeft de huidige inhoud van de onderliggende buffer terug.
- class io.BytesIO(string: bytes = b'')¶
Bestandachtig object in het geheugen voor invoer/uitvoer in binaire modus (vergelijkbaar met een normaal bestand dat is geopend met de “b”-modifier). De initiële inhoud kan worden opgegeven met de parameter string (die een bytes-object moet zijn). Instanties ondersteunen ook het contextmanagerprotocol (bruikbaar in een
with-statement).- read(size: int = -1) bytes¶
Lees en geef maximaal size bytes terug. Als size wordt weggelaten of negatief is, wordt alle resterende inhoud gelezen en teruggegeven.
- readline(size: int = -1) bytes¶
Lees en geef één regel terug. Als size wordt opgegeven, worden er maximaal size bytes gelezen.
- readinto(buf: bytearray) int¶
Lees in de vooraf toegewezen, beschrijfbare buffer buf en geef het aantal gelezen bytes terug.
- seek(offset: int, whence: int = 0) int¶
Wijzig de streampositie naar offset ten opzichte van whence (
0= begin,1= huidige,2= einde) en geef de nieuwe absolute positie terug.
- close() None¶
Sluit de stream en geef de onderliggende buffer vrij. Verdere bewerkingen op een gesloten stream werpen
ValueError.
- class io.BytesIO(alloc_size: int)
Maak een leeg
BytesIO-object dat vooraf is toegewezen om maximaal alloc_size bytes te bevatten, zodat het schrijven van maximaal dat aantal bytes de buffer niet opnieuw zal toewijzen (waardoor een out-of-memory-situatie of geheugenfragmentatie wordt vermeden). Deze constructor is een MicroPython-uitbreiding die alleen wordt aanbevolen voor speciale gevallen en bibliotheken op systeemniveau, niet voor eindgebruikerstoepassingen.Verschil met CPython
Deze constructor is een MicroPython-uitbreiding.
- read(size: int = -1) bytes
Lees en geef maximaal size bytes terug. Als size wordt weggelaten of negatief is, wordt alle resterende inhoud gelezen en teruggegeven.
- readline(size: int = -1) bytes
Lees en geef één regel terug. Als size wordt opgegeven, worden er maximaal size bytes gelezen.
- readinto(buf: bytearray) int
Lees in de vooraf toegewezen, beschrijfbare buffer buf en geef het aantal gelezen bytes terug.
- seek(offset: int, whence: int = 0) int
Wijzig de streampositie naar offset ten opzichte van whence (
0= begin,1= huidige,2= einde) en geef de nieuwe absolute positie terug.
- tell() int
Geeft de huidige streampositie terug.
- flush() None
Maak de schrijfbuffers leeg. Dit is een no-op voor een stream in het geheugen.
- close() None
Sluit de stream en geef de onderliggende buffer vrij. Verdere bewerkingen op een gesloten stream werpen
ValueError.
- getvalue() bytes
Geeft de huidige inhoud van de onderliggende buffer terug.