io — fluxos de entrada/saída¶
Este módulo contém tipos adicionais de objetos stream (semelhantes a ficheiros) e funções auxiliares. Expõe a função incorporada open() juntamente com buffers de texto e binários em memória (StringIO, BytesIO) que implementam a interface padrão de fluxo read/write/seek.
Hierarquia conceptual¶
Diferença em relação ao CPython
A hierarquia conceptual de classes base de fluxos é simplificada no MicroPython, conforme descrito nesta secção.
As classes base (abstratas) de fluxo, que servem de fundação para o comportamento de todas as classes concretas, obedecem a algumas dicotomias (classificações aos pares) no CPython. No MicroPython, estas são de certo modo simplificadas e tornadas implícitas para alcançar maior eficiência e poupar recursos.
Uma dicotomia importante no CPython é a de fluxos com e sem buffer. No MicroPython, todos os fluxos são atualmente sem buffer. Isto deve-se ao facto de todos os sistemas operativos modernos, e até muitos RTOS e controladores de sistemas de ficheiros, já realizarem buffering do seu lado. Adicionar mais uma camada de buffering é contraproducente (um problema conhecido como «bufferbloat») e consome memória preciosa. Note-se que ainda existem casos em que o buffering pode ser útil, pelo que poderemos introduzir suporte opcional de buffering numa fase posterior.
Mas no CPython, outra dicotomia importante está ligada ao «buffering» – se um fluxo pode ou não sofrer leituras/escritas curtas. Uma leitura curta ocorre quando o utilizador pede, por exemplo, 10 bytes de um fluxo, mas recebe menos; o mesmo se aplica às escritas. No CPython, os fluxos sem buffer ficam automaticamente sujeitos a operações curtas, enquanto os com buffer garantem a sua ausência. A ausência de leituras/escritas curtas é uma característica importante, pois permite desenvolver programas mais concisos e eficientes – algo altamente desejável no MicroPython. Assim, embora o MicroPython não suporte fluxos com buffer, oferece fluxos sem operações curtas. Se existirão ou não operações curtas depende das necessidades de cada classe em particular, mas recomenda-se vivamente aos programadores que privilegiem o comportamento sem operações curtas, pelas razões acima indicadas. Por exemplo, os sockets do MicroPython garantem a ausência de leituras/escritas curtas. De facto, neste momento não existe nenhum exemplo de classe de fluxo com operações curtas no núcleo, e tal classe seria específica para hardware particular.
O comportamento sem operações curtas torna-se complicado no caso de fluxos não bloqueantes – o comportamento bloqueante versus não bloqueante sendo outra dicotomia do CPython, totalmente suportada pelo MicroPython. Os fluxos não bloqueantes nunca aguardam pela chegada de dados nem pela possibilidade de escrever – leem/escrevem o que for possível, ou sinalizam a ausência de dados (ou a incapacidade de escrever dados). Claramente, isto entra em conflito com a política de «sem operações curtas» e, de facto, a combinação de fluxos não bloqueantes com buffer (e portanto sem operações curtas) é complicada no CPython – em alguns locais tal combinação é proibida, noutros é indefinida ou simplesmente não documentada, e noutros ainda levanta exceções prolixas. A questão é muito mais simples no MicroPython: os fluxos não bloqueantes são importantes para operações assíncronas eficientes, pelo que esta propriedade prevalece sobre a de «sem operações curtas». Assim, enquanto os fluxos bloqueantes evitarão leituras/escritas curtas sempre que possível (o único caso em que ocorre uma leitura curta é ao atingir o fim do ficheiro, ou em caso de erro – mas os erros não devolvem dados curtos, levantam exceções), os fluxos não bloqueantes podem produzir dados curtos para evitar bloquear a operação.
A dicotomia final é entre fluxos binários e de texto. O MicroPython suporta naturalmente ambos, mas enquanto no CPython os fluxos de texto são inerentemente com buffer, no MicroPython não são. (De facto, esse é um dos casos para os quais poderemos introduzir suporte de buffering.)
Note-se que, por razões de eficiência, o MicroPython não fornece classes base abstratas correspondentes à hierarquia acima, e não é possível implementar nem derivar uma classe de fluxo em Python puro.
Funções¶
Classes¶
- class io.IOBase¶
Classe base para objetos de fluxo («semelhantes a ficheiros»). As subclasses concretas implementam os métodos I/O de baixo nível abaixo (
readinto,write,ioctl); o runtime constrói o protocolo de fluxo de alto nível (read,readline,readlines,close, iteração) sobre eles, pelo que todas as instâncias de fluxo suportam esses métodos mesmo quando a subclasse não os define.Métodos de implementação (redefina-os numa subclasse):
- readinto(buf: bytearray) int | None¶
Lê bytes para o buffer gravável buf. Devolve o número de bytes lidos,
0no fim do fluxo, ouNonese não houver dados disponíveis neste momento (para um fluxo não bloqueante).
- write(buf: bytes) int | None¶
Escreve os bytes em buf. Devolve o número de bytes escritos, ou
Nonese a escrita não puder ser realizada neste momento (para um fluxo não bloqueante).
- ioctl(request: int, arg: int) int¶
Controla o fluxo/dispositivo subjacente. request é um dos códigos de pedido
MP_STREAM_*. Devolve um valor não negativo em caso de sucesso, ou um valor negativoerrnoem caso de erro.
Métodos do protocolo de fluxo (disponíveis em todas as instâncias de fluxo):
- read(size: int = -1)¶
Lê e devolve até size bytes (ou caracteres, em modo de texto). Se size for omitido ou negativo, lê até ao fim do fluxo. Devolve
bytespara fluxos binários estrpara fluxos de texto; um resultado vazio indica o fim do fluxo.
- readline(size: int = -1)¶
Lê e devolve uma linha, incluindo o carácter de nova linha final, se presente. Se size for especificado, são lidos no máximo size bytes (ou caracteres). Devolve um
bytes/strvazio no fim do fluxo.
- readlines() list¶
Lê até ao fim do fluxo e devolve uma
listde linhas, cada uma com a sua nova linha final.
- close() None¶
Fecha o fluxo e liberta quaisquer recursos subjacentes. Operações sobre um fluxo fechado levantam
OSError(ouValueErrorpara fluxos em memória).
- seek(offset: int, whence: int = 0) int¶
Altera a posição atual do fluxo para offset bytes em relação a whence (
0= início do fluxo,1= posição atual,2= fim do fluxo). Devolve a nova posição absoluta. LançaOSErrornum fluxo que não seja posicionável.
- flush() None¶
Descarrega quaisquer buffers de escrita, enviando os dados pendentes para o dispositivo ou ficheiro subjacente. Não tem efeito em fluxos que não utilizem buffer.
Iterar diretamente sobre um fluxo produz uma linha por iteração – equivalente a chamar
readline()em ciclo até ser devolvida a sentinela de fim de fluxo (linha vazia). Um fluxo também suporta o protocolo de gestor de contexto, pelo quewith open(...) as f:fecha o fluxo automaticamente.Nota
O módulo de fluxo do MicroPython também expõe auxiliares C com sufixo «1» –
mp_stream_read1_obj,mp_stream_readinto1_objemp_stream_write1_obj– que realizam uma única chamada I/O subjacente em vez de iterar até à satisfação completa do pedido. São utilizados internamente por classes comomachine.UARTpara implementar os seus própriosread/write– mas nenhuma classe de fluxo padrão os disponibiliza como métodos Python-invocáveisread1/readinto1/write1.
- class io.StringIO(string: str = '')¶
Objeto semelhante a ficheiro em memória para entrada/saída em modo de texto (semelhante a um ficheiro normal aberto com o modificador «t»). O conteúdo inicial pode ser especificado com o parâmetro string (que deverá ser uma string normal). As instâncias também suportam o protocolo de gestor de contexto (utilizável numa instrução
with).- read(size: int = -1) str¶
Lê e devolve até size caracteres. Se size for omitido ou negativo, lê e devolve todo o conteúdo restante.
- readline(size: int = -1) str¶
Lê e devolve uma linha. Se size for especificado, são lidos no máximo size caracteres.
- readinto(buf: bytearray) int¶
Lê para o buffer gravável pré-alocado buf e devolve o número de bytes lidos.
- seek(offset: int, whence: int = 0) int¶
Altera a posição do fluxo para offset em relação a whence (
0= início,1= atual,2= fim) e devolve a nova posição absoluta.
- flush() None¶
Descarrega os buffers de escrita. Esta operação não tem efeito para um fluxo em memória.
- close() None¶
Fecha o fluxo e liberta o buffer subjacente. Operações posteriores sobre um fluxo fechado levantam
ValueError.
- class io.StringIO(alloc_size: int)
Cria um objeto
StringIOvazio pré-alocado para conter até alloc_size bytes, de modo que escrever até esse número de bytes não irá realocar o buffer (evitando uma situação de falta de memória ou fragmentação de memória). Este construtor é uma extensão do MicroPython recomendada apenas para casos especiais e bibliotecas de sistema, não para aplicações de utilizador final.Diferença em relação ao CPython
Este construtor é uma extensão do MicroPython.
- read(size: int = -1) str
Lê e devolve até size caracteres. Se size for omitido ou negativo, lê e devolve todo o conteúdo restante.
- readline(size: int = -1) str
Lê e devolve uma linha. Se size for especificado, são lidos no máximo size caracteres.
- readinto(buf: bytearray) int
Lê para o buffer gravável pré-alocado buf e devolve o número de bytes lidos.
- seek(offset: int, whence: int = 0) int
Altera a posição do fluxo para offset em relação a whence (
0= início,1= atual,2= fim) e devolve a nova posição absoluta.
- tell() int
Devolve a posição atual do fluxo.
- flush() None
Descarrega os buffers de escrita. Esta operação não tem efeito para um fluxo em memória.
- close() None
Fecha o fluxo e liberta o buffer subjacente. Operações posteriores sobre um fluxo fechado levantam
ValueError.
- getvalue() str
Devolve o conteúdo atual do buffer subjacente.
- class io.BytesIO(string: bytes = b'')¶
Objeto semelhante a ficheiro em memória para entrada/saída em modo binário (semelhante a um ficheiro normal aberto com o modificador «b»). O conteúdo inicial pode ser especificado com o parâmetro string (que deverá ser um objeto bytes). As instâncias também suportam o protocolo de gestor de contexto (utilizável numa instrução
with).- read(size: int = -1) bytes¶
Lê e devolve até size bytes. Se size for omitido ou negativo, lê e devolve todo o conteúdo restante.
- readline(size: int = -1) bytes¶
Lê e devolve uma linha. Se size for especificado, são lidos no máximo size bytes.
- readinto(buf: bytearray) int¶
Lê para o buffer gravável pré-alocado buf e devolve o número de bytes lidos.
- seek(offset: int, whence: int = 0) int¶
Altera a posição do fluxo para offset em relação a whence (
0= início,1= atual,2= fim) e devolve a nova posição absoluta.
- flush() None¶
Descarrega os buffers de escrita. Esta operação não tem efeito para um fluxo em memória.
- close() None¶
Fecha o fluxo e liberta o buffer subjacente. Operações posteriores sobre um fluxo fechado levantam
ValueError.
- class io.BytesIO(alloc_size: int)
Cria um objeto
BytesIOvazio pré-alocado para conter até alloc_size bytes, de modo que escrever até esse número de bytes não irá realocar o buffer (evitando uma situação de falta de memória ou fragmentação de memória). Este construtor é uma extensão do MicroPython recomendada apenas para casos especiais e bibliotecas de sistema, não para aplicações de utilizador final.Diferença em relação ao CPython
Este construtor é uma extensão do MicroPython.
- read(size: int = -1) bytes
Lê e devolve até size bytes. Se size for omitido ou negativo, lê e devolve todo o conteúdo restante.
- readline(size: int = -1) bytes
Lê e devolve uma linha. Se size for especificado, são lidos no máximo size bytes.
- readinto(buf: bytearray) int
Lê para o buffer gravável pré-alocado buf e devolve o número de bytes lidos.
- seek(offset: int, whence: int = 0) int
Altera a posição do fluxo para offset em relação a whence (
0= início,1= atual,2= fim) e devolve a nova posição absoluta.
- tell() int
Devolve a posição atual do fluxo.
- flush() None
Descarrega os buffers de escrita. Esta operação não tem efeito para um fluxo em memória.
- close() None
Fecha o fluxo e liberta o buffer subjacente. Operações posteriores sobre um fluxo fechado levantam
ValueError.
- getvalue() bytes
Devolve o conteúdo atual do buffer subjacente.