io — ulazno/izlazni tokovi¶
Ovaj modul sadrži dodatne tipove objekata stream (sličnih datotekama) te pomoćne funkcije. Izlaže ugrađenu funkciju open() zajedno s tekstualnim i binarnim međuspremnicima u memoriji (StringIO, BytesIO) koji implementiraju standardno sučelje tokova read/write/seek.
Konceptualna hijerarhija¶
Razlika u odnosu na CPython
Konceptualna hijerarhija osnovnih klasa tokova pojednostavljena je u MicroPythonu, kako je opisano u ovom odjeljku.
(Apstraktne) osnovne klase tokova, koje služe kao temelj za ponašanje svih konkretnih klasa, u CPythonu se pridržavaju nekoliko dihotomija (razvrstavanja u parove). U MicroPythonu su one donekle pojednostavljene i učinjene implicitnima radi postizanja veće učinkovitosti i uštede resursa.
Važna dihotomija u CPythonu jest razlika između tokova bez međuspremnika i tokova s međuspremnikom. U MicroPythonu su trenutačno svi tokovi bez međuspremnika. To je zato što svi moderni operativni sustavi, pa čak i mnogi RTOS-ovi i upravljački programi datotečnih sustava, već obavljaju međupohranu na svojoj strani. Dodavanje još jednog sloja međupohrane kontraproduktivno je (problem poznat kao „bufferbloat”) i troši dragocjenu memoriju. Imajte na umu da i dalje postoje slučajevi u kojima međupohrana može biti korisna, pa bismo naknadno mogli uvesti opcionalnu podršku za međupohranu.
Ali u CPythonu je još jedna važna dihotomija vezana uz „međupohranjenost” - radi se o tome može li tok dovesti do kratkih čitanja/pisanja ili ne. Kratko čitanje je kada korisnik zatraži npr. 10 bajtova iz toka, ali dobije manje; slično vrijedi za pisanja. U CPythonu su tokovi bez međuspremnika automatski podložni kratkim operacijama, dok tokovi s međuspremnikom jamče da do njih neće doći. Odsutnost kratkih čitanja/pisanja važna je značajka jer omogućuje razvoj sažetijih i učinkovitijih programa - što je vrlo poželjno za MicroPython. Dakle, iako MicroPython ne podržava tokove s međuspremnikom, ipak omogućuje tokove bez kratkih operacija. Hoće li doći do kratkih operacija ili ne ovisi o potrebama svake pojedine klase, no programerima se snažno savjetuje da iz gore navedenih razloga daju prednost ponašanju bez kratkih operacija. Na primjer, za MicroPython sockete jamči se da će izbjegavati kratka čitanja/pisanja. Zapravo, trenutačno u jezgri nema primjera klase toka s kratkim operacijama, a takva bi klasa bila specifična za određeni hardver.
Ponašanje bez kratkih operacija postaje zamršeno u slučaju neblokirajućih tokova, pri čemu je razlika između blokirajućeg i neblokirajućeg ponašanja još jedna CPython dihotomija koju MicroPython u potpunosti podržava. Neblokirajući tokovi nikada ne čekaju da podaci stignu ili budu zapisani - čitaju/pišu što god je moguće ili signaliziraju nedostatak podataka (ili mogućnosti pisanja podataka). Očito je da je to u sukobu s pravilom „bez kratkih operacija”, i doista, slučaj neblokirajućih tokova s međuspremnikom (a time i bez kratkih operacija) zamršen je u CPythonu - na nekim mjestima takva je kombinacija zabranjena, na nekima je nedefinirana ili jednostavno nedokumentirana, a u nekim slučajevima podiže opširne iznimke. Stvar je mnogo jednostavnija u MicroPythonu: neblokirajući tokovi važni su za učinkovite asinkrone operacije, pa ovo svojstvo prevladava nad onim „bez kratkih operacija”. Dakle, iako će blokirajući tokovi izbjegavati kratka čitanja/pisanja kad god je to moguće (jedini slučaj kratkog čitanja jest kada se dosegne kraj datoteke ili u slučaju pogreške (no pogreške ne vraćaju kratke podatke, već podižu iznimke)), neblokirajući tokovi mogu proizvesti kratke podatke kako bi izbjegli blokiranje operacije.
Posljednja dihotomija je razlika između binarnih i tekstualnih tokova. MicroPython ih, naravno, podržava, ali dok su u CPythonu tekstualni tokovi inherentno s međuspremnikom, u MicroPythonu to nisu. (Doista, to je jedan od slučajeva za koje bismo mogli uvesti podršku za međupohranu.)
Imajte na umu da MicroPython radi učinkovitosti ne pruža apstraktne osnovne klase koje odgovaraju gornjoj hijerarhiji, te nije moguće implementirati ili izvesti potklasu klase toka u čistom Pythonu.
Funkcije¶
Klase¶
- class io.IOBase¶
Osnovna klasa za objekte tokova („sličnih datotekama”). Konkretne potklase implementiraju niskorazinske I/O metode navedene u nastavku (
readinto,write,ioctl); izvršno okruženje na njima gradi viši protokol tokova (read,readline,readlines,close, iteracija), pa svaka instanca toka podržava te metode čak i kada ih potklasa ne definira.Implementacijske metode (nadjačajte ih u potklasi):
- readinto(buf: bytearray) int | None¶
Čita bajtove u zapisivi međuspremnik buf. Vraća broj pročitanih bajtova,
0na kraju toka iliNoneako trenutačno nema dostupnih podataka (za neblokirajući tok).
- write(buf: bytes) int | None¶
Zapisuje bajtove iz buf. Vraća broj zapisanih bajtova ili
Noneako se zapisivanje trenutačno ne može izvršiti (za neblokirajući tok).
- ioctl(request: int, arg: int) int¶
Upravlja temeljnim tokom/uređajem. request je jedan od
MP_STREAM_*kodova zahtjeva. Vraća nenegativnu vrijednost u slučaju uspjeha ili negativnuerrnovrijednost u slučaju pogreške.
Metode protokola tokova (dostupne na svakoj instanci toka):
- read(size: int = -1)¶
Čita i vraća najviše size bajtova (ili znakova, u tekstualnom načinu). Ako je size izostavljen ili negativan, čita do kraja toka. Vraća
bytesza binarne tokove istrza tekstualne tokove; prazan rezultat označava kraj toka.
- readline(size: int = -1)¶
Čita i vraća jedan redak, uključujući završni znak novog retka ako je prisutan. Ako je zadan size, čita se najviše size bajtova (ili znakova). Na kraju toka vraća prazan
bytes/str.
- readlines() list¶
Čita do kraja toka i vraća
listredaka, svaki sa svojim završnim znakom novog retka.
- close() None¶
Zatvara tok i oslobađa sve temeljne resurse. Operacije nad zatvorenim tokom podižu
OSError(iliValueErrorza tokove u memoriji).
- seek(offset: int, whence: int = 0) int¶
Mijenja trenutačni položaj u toku na offset bajtova relativno na whence (
0= početak toka,1= trenutačni položaj,2= kraj toka). Vraća novi apsolutni položaj. PodižeOSErrorna toku po kojem se ne može pozicionirati.
- flush() None¶
Prazni sve međuspremnike za pisanje, prosljeđujući podatke koji čekaju temeljnom uređaju ili datoteci. Bez učinka na tokovima koji ne koriste međuspremnik.
Izravna iteracija toka pri svakom prolazu daje jedan redak – ekvivalentno pozivanju
readline()u petlji dok se ne vrati graničnik praznog retka koji označava kraj toka. Tok također podržava protokol upravitelja konteksta, pawith open(...) as f:automatski zatvara tok.Napomena
MicroPythonov modul za tokove izlaže i C pomoćnike s nastavkom „1”
mp_stream_read1_obj,mp_stream_readinto1_objimp_stream_write1_objkoji obavljaju jedan temeljni I/O poziv umjesto petlje sve dok zahtjev nije potpuno ispunjen. Njih interno koriste klase poputmachine.UARTza implementaciju vlastitogread/write– ali nijedna standardna klasa toka ne veže ih kao metoderead1/readinto1/write1pozivne iz Pythona.
- class io.StringIO(string: str = '')¶
Objekt u memoriji sličan datoteci za ulaz/izlaz u tekstualnom načinu (sličan običnoj datoteci otvorenoj s modifikatorom „t”). Početni sadržaj može se zadati parametrom string (koji bi trebao biti običan string). Instance također podržavaju protokol upravitelja konteksta (upotrebljiv u izjavi
with).- read(size: int = -1) str¶
Čita i vraća najviše size znakova. Ako je size izostavljen ili negativan, čita i vraća sav preostali sadržaj.
- readline(size: int = -1) str¶
Čita i vraća jedan redak. Ako je zadan size, čita se najviše size znakova.
- readinto(buf: bytearray) int¶
Čita u unaprijed alocirani, zapisivi međuspremnik buf i vraća broj pročitanih bajtova.
- seek(offset: int, whence: int = 0) int¶
Mijenja položaj u toku na offset relativno na whence (
0= početak,1= trenutačni,2= kraj) i vraća novi apsolutni položaj.
- close() None¶
Zatvara tok i oslobađa temeljni međuspremnik. Daljnje operacije nad zatvorenim tokom podižu
ValueError.
- class io.StringIO(alloc_size: int)
Stvara prazan
StringIOobjekt unaprijed alociran za pohranu do alloc_size bajtova, tako da zapisivanje do toliko bajtova neće ponovno alocirati međuspremnik (izbjegavajući stanje nedostatka memorije ili fragmentaciju memorije). Ovaj je konstruktor MicroPython proširenje preporučeno samo za posebne slučajeve i biblioteke na razini sustava, a ne za aplikacije krajnjih korisnika.Razlika u odnosu na CPython
Ovaj je konstruktor MicroPython proširenje.
- read(size: int = -1) str
Čita i vraća najviše size znakova. Ako je size izostavljen ili negativan, čita i vraća sav preostali sadržaj.
- readline(size: int = -1) str
Čita i vraća jedan redak. Ako je zadan size, čita se najviše size znakova.
- readinto(buf: bytearray) int
Čita u unaprijed alocirani, zapisivi međuspremnik buf i vraća broj pročitanih bajtova.
- seek(offset: int, whence: int = 0) int
Mijenja položaj u toku na offset relativno na whence (
0= početak,1= trenutačni,2= kraj) i vraća novi apsolutni položaj.
- tell() int
Vraća trenutačni položaj u toku.
- flush() None
Prazni međuspremnike za pisanje. Ovo nema učinka za tok u memoriji.
- close() None
Zatvara tok i oslobađa temeljni međuspremnik. Daljnje operacije nad zatvorenim tokom podižu
ValueError.
- getvalue() str
Vraća trenutačni sadržaj temeljnog međuspremnika.
- class io.BytesIO(string: bytes = b'')¶
Objekt u memoriji sličan datoteci za ulaz/izlaz u binarnom načinu (sličan običnoj datoteci otvorenoj s modifikatorom „b”). Početni sadržaj može se zadati parametrom string (koji bi trebao biti bytes objekt). Instance također podržavaju protokol upravitelja konteksta (upotrebljiv u izjavi
with).- read(size: int = -1) bytes¶
Čita i vraća najviše size bajtova. Ako je size izostavljen ili negativan, čita i vraća sav preostali sadržaj.
- readline(size: int = -1) bytes¶
Čita i vraća jedan redak. Ako je zadan size, čita se najviše size bajtova.
- readinto(buf: bytearray) int¶
Čita u unaprijed alocirani, zapisivi međuspremnik buf i vraća broj pročitanih bajtova.
- seek(offset: int, whence: int = 0) int¶
Mijenja položaj u toku na offset relativno na whence (
0= početak,1= trenutačni,2= kraj) i vraća novi apsolutni položaj.
- close() None¶
Zatvara tok i oslobađa temeljni međuspremnik. Daljnje operacije nad zatvorenim tokom podižu
ValueError.
- class io.BytesIO(alloc_size: int)
Stvara prazan
BytesIOobjekt unaprijed alociran za pohranu do alloc_size bajtova, tako da zapisivanje do toliko bajtova neće ponovno alocirati međuspremnik (izbjegavajući stanje nedostatka memorije ili fragmentaciju memorije). Ovaj je konstruktor MicroPython proširenje preporučeno samo za posebne slučajeve i biblioteke na razini sustava, a ne za aplikacije krajnjih korisnika.Razlika u odnosu na CPython
Ovaj je konstruktor MicroPython proširenje.
- read(size: int = -1) bytes
Čita i vraća najviše size bajtova. Ako je size izostavljen ili negativan, čita i vraća sav preostali sadržaj.
- readline(size: int = -1) bytes
Čita i vraća jedan redak. Ako je zadan size, čita se najviše size bajtova.
- readinto(buf: bytearray) int
Čita u unaprijed alocirani, zapisivi međuspremnik buf i vraća broj pročitanih bajtova.
- seek(offset: int, whence: int = 0) int
Mijenja položaj u toku na offset relativno na whence (
0= početak,1= trenutačni,2= kraj) i vraća novi apsolutni položaj.
- tell() int
Vraća trenutačni položaj u toku.
- flush() None
Prazni međuspremnike za pisanje. Ovo nema učinka za tok u memoriji.
- close() None
Zatvara tok i oslobađa temeljni međuspremnik. Daljnje operacije nad zatvorenim tokom podižu
ValueError.
- getvalue() bytes
Vraća trenutačni sadržaj temeljnog međuspremnika.