io — fluxuri de intrare/ieșire¶
Acest modul conține tipuri suplimentare de obiecte stream (asemănătoare fișierelor) și funcții auxiliare. El expune funcția încorporată open() împreună cu tampoane text și binare în memorie (StringIO, BytesIO) care implementează interfața standard de flux read/write/seek.
Ierarhie conceptuală¶
Diferențe față de CPython
Ierarhia conceptuală a claselor de bază pentru fluxuri este simplificată în MicroPython, așa cum este descris în această secțiune.
Clasele de bază (abstracte) pentru fluxuri, care servesc drept fundament pentru comportamentul tuturor claselor concrete, respectă câteva dihotomii (clasificări pereche) în CPython. În MicroPython, acestea sunt oarecum simplificate și făcute implicite pentru a obține eficiențe mai mari și a economisi resurse.
O dihotomie importantă în CPython este cea dintre fluxurile fără tampon și cele cu tampon. În MicroPython, toate fluxurile sunt în prezent fără tampon. Aceasta se datorează faptului că toate sistemele de operare moderne, și chiar multe sisteme RTOS și drivere de sistem de fișiere, efectuează deja buffering de partea lor. Adăugarea unui alt strat de buffering este contraproductivă (o problemă cunoscută drept „bufferbloat”) și consumă memorie prețioasă. Rețineți că există totuși cazuri în care bufferingul poate fi util, așa că am putea introduce suport opțional pentru buffering mai târziu.
Dar în CPython, o altă dihotomie importantă este legată de „existența tamponului” - anume dacă un flux poate produce citiri/scrieri scurte sau nu. O citire scurtă este atunci când un utilizator solicită, de exemplu, 10 octeți de la un flux, dar primește mai puțini; similar pentru scrieri. În CPython, fluxurile fără tampon sunt automat susceptibile la operații scurte, în timp ce cele cu tampon sunt garantate împotriva lor. Absența citirilor/scrierilor scurte este o trăsătură importantă, deoarece permite dezvoltarea unor programe mai concise și mai eficiente - ceea ce este foarte de dorit pentru MicroPython. Așadar, deși MicroPython nu acceptă fluxuri cu tampon, oferă totuși fluxuri fără operații scurte. Dacă vor exista sau nu operații scurte depinde de nevoile fiecărei clase în parte, dar dezvoltatorii sunt sfătuiți insistent să prefere comportamentul fără operații scurte din motivele expuse mai sus. De exemplu, socket-urile MicroPython sunt garantate să evite citirile/scrierile scurte. De fapt, în prezent nu există niciun exemplu de clasă de flux cu operații scurte în nucleu, iar o astfel de clasă ar fi specifică unui anumit hardware.
Comportamentul fără operații scurte devine delicat în cazul fluxurilor neblocante, comportamentul blocant vs. neblocant fiind o altă dihotomie din CPython, susținută complet de MicroPython. Fluxurile neblocante nu așteaptă niciodată ca datele să sosească sau să fie scrise - ele citesc/scriu ce este posibil, sau semnalează lipsa datelor (sau a capacității de a scrie date). În mod evident, acest lucru intră în conflict cu politica „fără operații scurte”, și într-adevăr, cazul fluxurilor neblocante cu tampon (și deci fără operații scurte) este complicat în CPython - în unele locuri o astfel de combinație este interzisă, în altele este nedefinită sau pur și simplu nedocumentată, în unele cazuri ridică excepții detaliate. Lucrurile sunt mult mai simple în MicroPython: fluxurile neblocante sunt importante pentru operații asincrone eficiente, așa că această proprietate prevalează asupra celei „fără operații scurte”. Astfel, în timp ce fluxurile blocante vor evita citirile/scrierile scurte ori de câte ori este posibil (singurul caz de a obține o citire scurtă fiind atingerea sfârșitului de fișier sau cazul unei erori (dar erorile nu returnează date scurte, ci ridică excepții)), fluxurile neblocante pot produce date scurte pentru a evita blocarea operației.
Ultima dihotomie este cea dintre fluxurile binare și cele text. MicroPython le acceptă desigur pe acestea, dar în timp ce în CPython fluxurile text sunt inerent cu tampon, în MicroPython ele nu sunt. (Într-adevăr, acesta este unul dintre cazurile pentru care am putea introduce suport pentru buffering.)
Rețineți că, din motive de eficiență, MicroPython nu oferă clase de bază abstracte corespunzătoare ierarhiei de mai sus și nu este posibil să implementați sau să derivați o clasă de flux în Python pur.
Funcții¶
Clase¶
- class io.IOBase¶
Clasa de bază pentru obiectele de tip flux („asemănătoare fișierelor”). Subclasele concrete implementează metodele I/O de nivel scăzut de mai jos (
readinto,write,ioctl); runtime-ul construiește protocolul de flux de nivel mai înalt (read,readline,readlines,close, iterare) deasupra lor, astfel încât fiecare instanță de flux acceptă acele metode chiar și atunci când subclasa nu le definește.Metode de implementare (suprascrieți-le într-o subclasă):
- readinto(buf: bytearray) int | None¶
Citește octeți în tamponul inscriptibil buf. Returnează numărul de octeți citiți,
0la sfârșitul fluxului, sauNonedacă nu sunt date disponibile chiar acum (pentru un flux neblocant).
- write(buf: bytes) int | None¶
Scrie octeții din buf. Returnează numărul de octeți scriși, sau
Nonedacă scrierea nu poate fi efectuată chiar acum (pentru un flux neblocant).
- ioctl(request: int, arg: int) int¶
Controlează fluxul/dispozitivul subiacent. request este unul dintre codurile de cerere
MP_STREAM_*. Returnează o valoare nenegativă în caz de succes, sau o valoareerrnonegativă în caz de eroare.
Metodele protocolului de flux (disponibile pe fiecare instanță de flux):
- read(size: int = -1)¶
Citește și returnează până la size octeți (sau caractere, în mod text). Dacă size este omis sau negativ, citește până la sfârșitul fluxului. Returnează
bytespentru fluxurile binare șistrpentru fluxurile text; un rezultat gol indică sfârșitul fluxului.
- readline(size: int = -1)¶
Citește și returnează o linie, inclusiv caracterul de linie nouă final dacă este prezent. Dacă size este furnizat, se citesc cel mult size octeți (sau caractere). Returnează un
bytes/strgol la sfârșitul fluxului.
- readlines() list¶
Citește până la sfârșitul fluxului și returnează o
listde linii, fiecare cu caracterul său de linie nouă final.
- close() None¶
Închide fluxul și eliberează orice resurse subiacente. Operațiile pe un flux închis ridică
OSError(sauValueErrorpentru fluxurile în memorie).
- seek(offset: int, whence: int = 0) int¶
Schimbă poziția curentă a fluxului la offset octeți față de whence (
0= începutul fluxului,1= poziția curentă,2= sfârșitul fluxului). Returnează noua poziție absolută. RidicăOSErrorpe un flux care nu permite poziționarea.
- flush() None¶
Golește orice tampoane de scriere, împingând datele în așteptare către dispozitivul sau fișierul subiacent. Nu are efect pe fluxurile care nu folosesc tampon.
Iterarea directă a unui flux produce o linie per iterație – echivalent cu apelarea
readline()într-o buclă până când este returnat marcajul de sfârșit de flux reprezentat de linia goală. Un flux acceptă de asemenea protocolul de gestionar de context, astfel încâtwith open(...) as f:închide fluxul automat.Notă
Modulul de fluxuri al MicroPython expune de asemenea funcții auxiliare C cu sufixul „1”
mp_stream_read1_obj,mp_stream_readinto1_objșimp_stream_write1_objcare efectuează un singur apel I/O subiacent în loc să facă o buclă până când cererea este satisfăcută complet. Ele sunt folosite intern de clase precummachine.UARTpentru a-și implementa propriile metoderead/write– dar nicio clasă de flux standard nu le leagă ca metode Python apelabileread1/readinto1/write1.
- class io.StringIO(string: str = '')¶
Obiect în memorie asemănător unui fișier pentru intrare/ieșire în mod text (similar unui fișier normal deschis cu modificatorul „t”). Conținutul inițial poate fi specificat cu parametrul string (care ar trebui să fie un șir normal). Instanțele acceptă de asemenea protocolul de gestionar de context (utilizabil într-o instrucțiune
with).- read(size: int = -1) str¶
Citește și returnează până la size caractere. Dacă size este omis sau negativ, citește și returnează tot conținutul rămas.
- readline(size: int = -1) str¶
Citește și returnează o linie. Dacă size este furnizat, se citesc cel mult size caractere.
- readinto(buf: bytearray) int¶
Citește în tamponul inscriptibil prealocat buf și returnează numărul de octeți citiți.
- seek(offset: int, whence: int = 0) int¶
Schimbă poziția fluxului la offset față de whence (
0= început,1= curent,2= sfârșit) și returnează noua poziție absolută.
- close() None¶
Închide fluxul și eliberează tamponul subiacent. Operațiile ulterioare pe un flux închis ridică
ValueError.
- class io.StringIO(alloc_size: int)
Creează un obiect
StringIOgol prealocat pentru a păstra până la alloc_size octeți, astfel încât scrierea a până la acel număr de octeți nu va realoca tamponul (evitând o situație de epuizare a memoriei sau fragmentarea memoriei). Acest constructor este o extensie MicroPython recomandată doar pentru cazuri speciale și biblioteci la nivel de sistem, nu pentru aplicațiile utilizatorului final.Diferențe față de CPython
Acest constructor este o extensie MicroPython.
- read(size: int = -1) str
Citește și returnează până la size caractere. Dacă size este omis sau negativ, citește și returnează tot conținutul rămas.
- readline(size: int = -1) str
Citește și returnează o linie. Dacă size este furnizat, se citesc cel mult size caractere.
- readinto(buf: bytearray) int
Citește în tamponul inscriptibil prealocat buf și returnează numărul de octeți citiți.
- seek(offset: int, whence: int = 0) int
Schimbă poziția fluxului la offset față de whence (
0= început,1= curent,2= sfârșit) și returnează noua poziție absolută.
- tell() int
Returnează poziția curentă a fluxului.
- flush() None
Golește tampoanele de scriere. Aceasta nu are efect pentru un flux în memorie.
- close() None
Închide fluxul și eliberează tamponul subiacent. Operațiile ulterioare pe un flux închis ridică
ValueError.
- getvalue() str
Returnează conținutul curent al tamponului subiacent.
- class io.BytesIO(string: bytes = b'')¶
Obiect în memorie asemănător unui fișier pentru intrare/ieșire în mod binar (similar unui fișier normal deschis cu modificatorul „b”). Conținutul inițial poate fi specificat cu parametrul string (care ar trebui să fie un obiect bytes). Instanțele acceptă de asemenea protocolul de gestionar de context (utilizabil într-o instrucțiune
with).- read(size: int = -1) bytes¶
Citește și returnează până la size octeți. Dacă size este omis sau negativ, citește și returnează tot conținutul rămas.
- readline(size: int = -1) bytes¶
Citește și returnează o linie. Dacă size este furnizat, se citesc cel mult size octeți.
- readinto(buf: bytearray) int¶
Citește în tamponul inscriptibil prealocat buf și returnează numărul de octeți citiți.
- seek(offset: int, whence: int = 0) int¶
Schimbă poziția fluxului la offset față de whence (
0= început,1= curent,2= sfârșit) și returnează noua poziție absolută.
- close() None¶
Închide fluxul și eliberează tamponul subiacent. Operațiile ulterioare pe un flux închis ridică
ValueError.
- class io.BytesIO(alloc_size: int)
Creează un obiect
BytesIOgol prealocat pentru a păstra până la alloc_size octeți, astfel încât scrierea a până la acel număr de octeți nu va realoca tamponul (evitând o situație de epuizare a memoriei sau fragmentarea memoriei). Acest constructor este o extensie MicroPython recomandată doar pentru cazuri speciale și biblioteci la nivel de sistem, nu pentru aplicațiile utilizatorului final.Diferențe față de CPython
Acest constructor este o extensie MicroPython.
- read(size: int = -1) bytes
Citește și returnează până la size octeți. Dacă size este omis sau negativ, citește și returnează tot conținutul rămas.
- readline(size: int = -1) bytes
Citește și returnează o linie. Dacă size este furnizat, se citesc cel mult size octeți.
- readinto(buf: bytearray) int
Citește în tamponul inscriptibil prealocat buf și returnează numărul de octeți citiți.
- seek(offset: int, whence: int = 0) int
Schimbă poziția fluxului la offset față de whence (
0= început,1= curent,2= sfârșit) și returnează noua poziție absolută.
- tell() int
Returnează poziția curentă a fluxului.
- flush() None
Golește tampoanele de scriere. Aceasta nu are efect pentru un flux în memorie.
- close() None
Închide fluxul și eliberează tamponul subiacent. Operațiile ulterioare pe un flux închis ridică
ValueError.
- getvalue() bytes
Returnează conținutul curent al tamponului subiacent.