io — flussi di input/output¶
Questo modulo contiene tipi aggiuntivi di oggetti stream (simili a file) e funzioni di supporto. Espone la funzione builtin open() insieme a buffer di testo e binari in memoria (StringIO, BytesIO) che implementano l’interfaccia stream standard read/write/seek.
Gerarchia concettuale¶
Differenze rispetto a CPython
La gerarchia concettuale delle classi base degli stream è semplificata in MicroPython, come descritto in questa sezione.
Le classi base (astratte) degli stream, che fungono da fondamento per il comportamento di tutte le classi concrete, in CPython aderiscono ad alcune dicotomie (classificazioni a coppie). In MicroPython sono in qualche modo semplificate e rese implicite per ottenere maggiore efficienza e risparmiare risorse.
Un’importante dicotomia in CPython è quella tra stream con e senza buffer. In MicroPython, attualmente tutti gli stream sono privi di buffer. Questo perché tutti i sistemi operativi moderni, e perfino molti RTOS e driver di filesystem, eseguono già il buffering dalla loro parte. Aggiungere un ulteriore livello di buffering è controproducente (un problema noto come «bufferbloat») e occupa memoria preziosa. Si noti che esistono comunque casi in cui il buffering può essere utile, quindi potremmo introdurre il supporto opzionale al buffering in un secondo momento.
Ma in CPython un’altra importante dicotomia è legata alla «presenza di buffer»: se uno stream può incorrere o meno in letture/scritture parziali. Una lettura parziale si verifica quando un utente chiede ad esempio 10 byte da uno stream ma ne ottiene di meno, e analogamente per le scritture. In CPython, gli stream senza buffer sono automaticamente soggetti a operazioni parziali, mentre quelli con buffer ne sono garantiti immuni. L’assenza di letture/scritture parziali è una caratteristica importante, poiché consente di sviluppare programmi più concisi ed efficienti, qualcosa di altamente auspicabile per MicroPython. Pertanto, sebbene MicroPython non supporti gli stream con buffer, fornisce comunque stream senza operazioni parziali. Se ci saranno operazioni parziali o meno dipende dalle esigenze di ciascuna classe specifica, ma si raccomanda vivamente agli sviluppatori di privilegiare il comportamento senza operazioni parziali per i motivi sopra esposti. Ad esempio, i socket di MicroPython sono garantiti contro letture/scritture parziali. In realtà, al momento non esiste alcun esempio di classe stream con operazioni parziali nel core, e una tale classe sarebbe specifica per un particolare hardware.
Il comportamento senza operazioni parziali diventa complicato nel caso di stream non bloccanti, dato che il comportamento bloccante rispetto a quello non bloccante è un’altra dicotomia di CPython, pienamente supportata da MicroPython. Gli stream non bloccanti non attendono mai che i dati arrivino o vengano scritti: leggono/scrivono tutto ciò che è possibile, oppure segnalano la mancanza di dati (o la capacità di scrivere dati). Chiaramente, ciò è in conflitto con la politica di «assenza di operazioni parziali», e in effetti il caso degli stream non bloccanti con buffer (e quindi senza operazioni parziali) è intricato in CPython: in alcuni casi tale combinazione è vietata, in altri non è definita o semplicemente non documentata, in alcuni casi solleva eccezioni verbose. La questione è molto più semplice in MicroPython: gli stream non bloccanti sono importanti per operazioni asincrone efficienti, quindi questa proprietà prevale su quella dell“«assenza di operazioni parziali». Pertanto, mentre gli stream bloccanti evitano le letture/scritture parziali ogni volta che è possibile (l’unico caso per ottenere una lettura parziale è il raggiungimento della fine del file, oppure in caso di errore (ma gli errori non restituiscono dati parziali, bensì sollevano eccezioni)), gli stream non bloccanti possono produrre dati parziali per evitare di bloccare l’operazione.
L’ultima dicotomia è quella tra stream binari e di testo. MicroPython li supporta naturalmente, ma mentre in CPython gli stream di testo sono intrinsecamente dotati di buffer, in MicroPython non lo sono. (In effetti, questo è uno dei casi per cui potremmo introdurre il supporto al buffering.)
Si noti che, per motivi di efficienza, MicroPython non fornisce classi base astratte corrispondenti alla gerarchia sopra descritta, e non è possibile implementare, o derivare per sottoclasse, una classe stream in puro Python.
Funzioni¶
Classi¶
- class io.IOBase¶
Classe base per gli oggetti stream («simili a file»). Le sottoclassi concrete implementano i metodi di I/O di basso livello seguenti (
readinto,write,ioctl); il runtime costruisce su di essi il protocollo stream di più alto livello (read,readline,readlines,close, iterazione), così ogni istanza di stream supporta tali metodi anche quando la sottoclasse non li definisce.Metodi di implementazione (sovrascrivili in una sottoclasse):
- readinto(buf: bytearray) int | None¶
Legge byte nel buffer scrivibile buf. Restituisce il numero di byte letti,
0alla fine dello stream, oppureNonese al momento non sono disponibili dati (per uno stream non bloccante).
- write(buf: bytes) int | None¶
Scrive i byte in buf. Restituisce il numero di byte scritti, oppure
Nonese la scrittura non può essere eseguita al momento (per uno stream non bloccante).
- ioctl(request: int, arg: int) int¶
Controlla lo stream/dispositivo sottostante. request è uno dei codici di richiesta
MP_STREAM_*. Restituisce un valore non negativo in caso di successo, oppure un valoreerrnonegativo in caso di errore.
Metodi del protocollo stream (disponibili su ogni istanza di stream):
- read(size: int = -1)¶
Legge e restituisce fino a size byte (o caratteri, in modalità testo). Se size è omesso o negativo, legge fino alla fine dello stream. Restituisce
bytesper gli stream binari estrper gli stream di testo; un risultato vuoto indica la fine dello stream.
- readline(size: int = -1)¶
Legge e restituisce una riga, incluso il carattere di newline finale se presente. Se viene fornito size, vengono letti al massimo size byte (o caratteri). Restituisce un
bytes/strvuoto alla fine dello stream.
- readlines() list¶
Legge fino alla fine dello stream e restituisce una
listdi righe, ciascuna con il proprio newline finale.
- close() None¶
Chiude lo stream e rilascia eventuali risorse sottostanti. Le operazioni su uno stream chiuso sollevano
OSError(oppureValueErrorper gli stream in memoria).
- seek(offset: int, whence: int = 0) int¶
Cambia la posizione corrente dello stream a offset byte rispetto a whence (
0= inizio dello stream,1= posizione corrente,2= fine dello stream). Restituisce la nuova posizione assoluta. SollevaOSErrorsu uno stream non posizionabile.
- flush() None¶
Svuota eventuali buffer di scrittura, inviando i dati in sospeso al dispositivo o file sottostante. Non ha effetto sugli stream privi di buffer.
Iterando direttamente uno stream si ottiene una riga per iterazione, equivalente a chiamare
readline()in un ciclo finché non viene restituito il sentinel di fine stream (riga vuota). Uno stream supporta anche il protocollo context manager, quindiwith open(...) as f:chiude lo stream automaticamente.Nota
Il modulo stream di MicroPython espone anche gli helper C con suffisso «1»
mp_stream_read1_obj,mp_stream_readinto1_objemp_stream_write1_objche eseguono una singola chiamata di I/O sottostante invece di iterare finché la richiesta non è completamente soddisfatta. Vengono utilizzati internamente da classi comemachine.UARTper implementare le proprieread/write, ma nessuna classe stream standard li associa come metodiread1/readinto1/write1richiamabili da Python.
- class io.StringIO(string: str = '')¶
Oggetto in memoria simile a file per input/output in modalità testo (analogo a un normale file aperto con il modificatore «t»). Il contenuto iniziale può essere specificato con il parametro string (che deve essere una stringa normale). Le istanze supportano anche il protocollo context manager (utilizzabile in un’istruzione
with).- read(size: int = -1) str¶
Legge e restituisce fino a size caratteri. Se size è omesso o negativo, legge e restituisce tutto il contenuto rimanente.
- readline(size: int = -1) str¶
Legge e restituisce una riga. Se viene fornito size, vengono letti al massimo size caratteri.
- readinto(buf: bytearray) int¶
Legge nel buffer scrivibile pre-allocato buf e restituisce il numero di byte letti.
- seek(offset: int, whence: int = 0) int¶
Cambia la posizione dello stream a offset rispetto a whence (
0= inizio,1= corrente,2= fine) e restituisce la nuova posizione assoluta.
- close() None¶
Chiude lo stream e libera il buffer sottostante. Ulteriori operazioni su uno stream chiuso sollevano
ValueError.
- class io.StringIO(alloc_size: int)
Crea un oggetto
StringIOvuoto pre-allocato per contenere fino a alloc_size byte, in modo che la scrittura fino a tale quantità di byte non rialloca il buffer (evitando una situazione di esaurimento della memoria o la frammentazione della memoria). Questo costruttore è un’estensione di MicroPython consigliata solo per casi speciali e librerie di livello di sistema, non per le applicazioni dell’utente finale.Differenze rispetto a CPython
Questo costruttore è un’estensione di MicroPython.
- read(size: int = -1) str
Legge e restituisce fino a size caratteri. Se size è omesso o negativo, legge e restituisce tutto il contenuto rimanente.
- readline(size: int = -1) str
Legge e restituisce una riga. Se viene fornito size, vengono letti al massimo size caratteri.
- readinto(buf: bytearray) int
Legge nel buffer scrivibile pre-allocato buf e restituisce il numero di byte letti.
- seek(offset: int, whence: int = 0) int
Cambia la posizione dello stream a offset rispetto a whence (
0= inizio,1= corrente,2= fine) e restituisce la nuova posizione assoluta.
- tell() int
Restituisce la posizione corrente dello stream.
- flush() None
Svuota i buffer di scrittura. Non ha effetto per uno stream in memoria.
- close() None
Chiude lo stream e libera il buffer sottostante. Ulteriori operazioni su uno stream chiuso sollevano
ValueError.
- getvalue() str
Restituisce il contenuto corrente del buffer sottostante.
- class io.BytesIO(string: bytes = b'')¶
Oggetto in memoria simile a file per input/output in modalità binaria (analogo a un normale file aperto con il modificatore «b»). Il contenuto iniziale può essere specificato con il parametro string (che deve essere un oggetto bytes). Le istanze supportano anche il protocollo context manager (utilizzabile in un’istruzione
with).- read(size: int = -1) bytes¶
Legge e restituisce fino a size byte. Se size è omesso o negativo, legge e restituisce tutto il contenuto rimanente.
- readline(size: int = -1) bytes¶
Legge e restituisce una riga. Se viene fornito size, vengono letti al massimo size byte.
- readinto(buf: bytearray) int¶
Legge nel buffer scrivibile pre-allocato buf e restituisce il numero di byte letti.
- seek(offset: int, whence: int = 0) int¶
Cambia la posizione dello stream a offset rispetto a whence (
0= inizio,1= corrente,2= fine) e restituisce la nuova posizione assoluta.
- close() None¶
Chiude lo stream e libera il buffer sottostante. Ulteriori operazioni su uno stream chiuso sollevano
ValueError.
- class io.BytesIO(alloc_size: int)
Crea un oggetto
BytesIOvuoto pre-allocato per contenere fino a alloc_size byte, in modo che la scrittura fino a tale quantità di byte non rialloca il buffer (evitando una situazione di esaurimento della memoria o la frammentazione della memoria). Questo costruttore è un’estensione di MicroPython consigliata solo per casi speciali e librerie di livello di sistema, non per le applicazioni dell’utente finale.Differenze rispetto a CPython
Questo costruttore è un’estensione di MicroPython.
- read(size: int = -1) bytes
Legge e restituisce fino a size byte. Se size è omesso o negativo, legge e restituisce tutto il contenuto rimanente.
- readline(size: int = -1) bytes
Legge e restituisce una riga. Se viene fornito size, vengono letti al massimo size byte.
- readinto(buf: bytearray) int
Legge nel buffer scrivibile pre-allocato buf e restituisce il numero di byte letti.
- seek(offset: int, whence: int = 0) int
Cambia la posizione dello stream a offset rispetto a whence (
0= inizio,1= corrente,2= fine) e restituisce la nuova posizione assoluta.
- tell() int
Restituisce la posizione corrente dello stream.
- flush() None
Svuota i buffer di scrittura. Non ha effetto per uno stream in memoria.
- close() None
Chiude lo stream e libera il buffer sottostante. Ulteriori operazioni su uno stream chiuso sollevano
ValueError.
- getvalue() bytes
Restituisce il contenuto corrente del buffer sottostante.