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

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

Deschide un fișier. Funcția încorporată open() este un alias pentru această funcție. Parametrul mode este întotdeauna acceptat; suportul pentru alte argumente poate varia.

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, 0 la sfârșitul fluxului, sau None dacă 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 None dacă 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 valoare errno negativă î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ă bytes pentru fluxurile binare și str pentru 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 / str gol la sfârșitul fluxului.

readlines() list

Citește până la sfârșitul fluxului și returnează o list de 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 (sau ValueError pentru 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ă OSError pe un flux care nu permite poziționarea.

tell() int

Returnează poziția absolută curentă în flux. Echivalent cu seek(0, 1).

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ât with 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 și mp_stream_write1_obj care 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 precum machine.UART pentru a-și implementa propriile metode read / write – dar nicio clasă de flux standard nu le leagă ca metode Python apelabile read1 / 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.

write(s: str) int

Scrie șirul s și returnează numărul de caractere scrise.

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.StringIO(alloc_size: int)

Creează un obiect StringIO gol 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.

write(s: str) int

Scrie șirul s și returnează numărul de caractere scrise.

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.

write(b: bytes) int

Scrie obiectul de tip bytes b și returnează numărul de octeți scriș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.

class io.BytesIO(alloc_size: int)

Creează un obiect BytesIO gol 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.

write(b: bytes) int

Scrie obiectul de tip bytes b și returnează numărul de octeți scriș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.