io — fluxos de entrada/saída¶
Este módulo contém tipos adicionais de objetos stream (semelhantes a arquivos) e funções auxiliares. Ele expõe a função interna open() junto com buffers de texto e binários em memória (StringIO, BytesIO) que implementam a interface de fluxo padrão read/write/seek.
Hierarquia conceitual¶
Diferença em relação ao CPython
A hierarquia conceitual das classes base de fluxo é simplificada no MicroPython, conforme descrito nesta seção.
As classes base de fluxo (abstratas), que servem de fundamento para o comportamento de todas as classes concretas, aderem a algumas dicotomias (classificações em pares) no CPython. No MicroPython, elas são de certo modo simplificadas e tornadas implícitas para alcançar maior eficiência e economizar recursos.
Uma dicotomia importante no CPython é a de fluxos sem buffer versus fluxos com buffer. No MicroPython, todos os fluxos atualmente são sem buffer. Isso ocorre porque todos os sistemas operacionais modernos, e até muitos RTOSes e drivers de sistema de arquivos, já realizam o buffer do seu lado. Adicionar mais uma camada de buffer é contraproducente (um problema conhecido como “bufferbloat”) e consome memória preciosa. Observe que ainda há casos em que o buffer pode ser útil, então podemos introduzir suporte opcional a buffer em um momento posterior.
Mas no CPython, outra dicotomia importante está ligada à “presença de buffer” - se um fluxo pode ou não incorrer em leituras/escritas curtas. Uma leitura curta ocorre quando um usuário solicita, por exemplo, 10 bytes de um fluxo, mas recebe menos; o mesmo vale para escritas. No CPython, fluxos sem buffer são automaticamente suscetíveis a operações curtas, enquanto os fluxos com buffer garantem que elas não ocorram. A ausência de leituras/escritas curtas é uma característica importante, pois permite desenvolver programas mais concisos e eficientes - algo altamente desejável para o MicroPython. Assim, embora o MicroPython não suporte fluxos com buffer, ele ainda oferece fluxos sem operações curtas. Se haverá ou não operações curtas depende das necessidades de cada classe específica, mas recomenda-se fortemente que os desenvolvedores favoreçam o comportamento sem operações curtas pelos motivos expostos acima. Por exemplo, os sockets do MicroPython têm garantia de evitar leituras/escritas curtas. Na verdade, neste momento, não há exemplo de uma classe de fluxo com operações curtas no núcleo, e tal classe seria específica de um hardware particular.
O comportamento sem operações curtas torna-se complicado no caso de fluxos não bloqueantes, sendo o comportamento bloqueante versus não bloqueante outra dicotomia do CPython, totalmente suportada pelo MicroPython. Fluxos não bloqueantes nunca esperam que dados cheguem ou sejam escritos - eles leem/escrevem o que for possível, ou sinalizam a falta de dados (ou a impossibilidade de escrever dados). Claramente, isso conflita com a política de “ausência de operações curtas” e, de fato, o caso de fluxos não bloqueantes com buffer (e portanto sem operações curtas) é complicado no CPython - em alguns lugares tal combinação é proibida, em outros é indefinida ou simplesmente não documentada, e em alguns casos levanta exceções verbosas. A questão é muito mais simples no MicroPython: fluxos não bloqueantes são importantes para operações assíncronas eficientes, então essa propriedade prevalece sobre a de “ausência de operações curtas”. Assim, embora os fluxos bloqueantes evitem leituras/escritas curtas sempre que possível (o único caso em que se obtém uma leitura curta é se o fim do arquivo for alcançado, ou em caso de erro (mas erros não retornam dados curtos, e sim levantam exceções)), os fluxos não bloqueantes podem produzir dados curtos para evitar bloquear a operação.
A dicotomia final é a de fluxos binários versus fluxos de texto. O MicroPython, é claro, suporta ambos, mas enquanto no CPython os fluxos de texto possuem buffer inerentemente, no MicroPython não possuem. (De fato, esse é um dos casos para os quais podemos introduzir suporte a buffer.)
Observe que, por questões de eficiência, o MicroPython não fornece classes base abstratas correspondentes à hierarquia acima, e não é possível implementar, ou criar subclasse de, uma classe de fluxo em Python puro.
Funções¶
Classes¶
- class io.IOBase¶
Classe base para objetos de fluxo (“semelhantes a arquivos”). Subclasses concretas implementam os métodos de E/S de baixo nível abaixo (
readinto,write,ioctl); o runtime constrói sobre eles o protocolo de fluxo de mais alto nível (read,readline,readlines,close, iteração), de modo que toda instância de fluxo suporta esses métodos mesmo quando a subclasse não os define.Métodos de implementação (sobrescreva-os em uma subclasse):
- readinto(buf: bytearray) int | None¶
Lê bytes para o buffer gravável buf. Retorna o número de bytes lidos,
0no fim do fluxo, ouNonese não houver dados disponíveis no momento (para um fluxo não bloqueante).
- write(buf: bytes) int | None¶
Escreve os bytes em buf. Retorna o número de bytes escritos, ou
Nonese a escrita não puder ser realizada no momento (para um fluxo não bloqueante).
- ioctl(request: int, arg: int) int¶
Controla o fluxo/dispositivo subjacente. request é um dos códigos de requisição
MP_STREAM_*. Retorna um valor não negativo em caso de sucesso, ou um valorerrnonegativo em caso de erro.
Métodos do protocolo de fluxo (disponíveis em toda instância de fluxo):
- read(size: int = -1)¶
Lê e retorna até size bytes (ou caracteres, no modo texto). Se size for omitido ou negativo, lê até o fim do fluxo. Retorna
bytespara fluxos binários estrpara fluxos de texto; um resultado vazio indica o fim do fluxo.
- readline(size: int = -1)¶
Lê e retorna uma linha, incluindo o caractere de nova linha final, se houver. Se size for fornecido, no máximo size bytes (ou caracteres) são lidos. Retorna um
bytes/strvazio no fim do fluxo.
- readlines() list¶
Lê até o fim do fluxo e retorna uma
listde linhas, cada uma com sua nova linha final.
- close() None¶
Fecha o fluxo e libera quaisquer recursos subjacentes. Operações em 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 relativos a whence (
0= início do fluxo,1= posição atual,2= fim do fluxo). Retorna a nova posição absoluta. LevantaOSErrorem um fluxo que não permite reposicionamento.
- flush() None¶
Descarrega quaisquer buffers de escrita, enviando os dados pendentes para o dispositivo ou arquivo subjacente. Não tem efeito em fluxos que não utilizam buffer.
Iterar um fluxo diretamente produz uma linha por iteração – equivalente a chamar
readline()em um laço até que o sentinela de linha vazia indicando fim do fluxo seja retornado. Um fluxo também suporta o protocolo de gerenciador de contexto, entãowith open(...) as f:fecha o fluxo automaticamente.Nota
O módulo de fluxo do MicroPython também expõe os auxiliares em C com sufixo “1”
mp_stream_read1_obj,mp_stream_readinto1_objemp_stream_write1_objque realizam uma única chamada de E/S subjacente em vez de iterar até que a requisição seja totalmente satisfeita. Eles são usados internamente por classes comomachine.UARTpara implementar seus própriosread/write– mas nenhuma classe de fluxo padrão os vincula como métodosread1/readinto1/write1chamáveis em Python.
- class io.StringIO(string: str = '')¶
Objeto semelhante a arquivo em memória para entrada/saída em modo texto (similar a um arquivo normal aberto com o modificador “t”). O conteúdo inicial pode ser especificado com o parâmetro string (que deve ser uma string normal). As instâncias também suportam o protocolo de gerenciador de contexto (utilizável em uma instrução
with).- read(size: int = -1) str¶
Lê e retorna até size caracteres. Se size for omitido ou negativo, lê e retorna todo o conteúdo restante.
- readline(size: int = -1) str¶
Lê e retorna uma linha. Se size for fornecido, no máximo size caracteres são lidos.
- readinto(buf: bytearray) int¶
Lê para o buffer gravável pré-alocado buf e retorna o número de bytes lidos.
- seek(offset: int, whence: int = 0) int¶
Altera a posição do fluxo para offset relativo a whence (
0= início,1= atual,2= fim) e retorna a nova posição absoluta.
- close() None¶
Fecha o fluxo e libera o buffer subjacente. Operações adicionais em 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 a escrita de até essa quantidade de bytes não 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 nível de sistema, não para aplicações de usuário final.Diferença em relação ao CPython
Este construtor é uma extensão do MicroPython.
- read(size: int = -1) str
Lê e retorna até size caracteres. Se size for omitido ou negativo, lê e retorna todo o conteúdo restante.
- readline(size: int = -1) str
Lê e retorna uma linha. Se size for fornecido, no máximo size caracteres são lidos.
- readinto(buf: bytearray) int
Lê para o buffer gravável pré-alocado buf e retorna o número de bytes lidos.
- seek(offset: int, whence: int = 0) int
Altera a posição do fluxo para offset relativo a whence (
0= início,1= atual,2= fim) e retorna a nova posição absoluta.
- tell() int
Retorna a posição atual do fluxo.
- flush() None
Descarrega os buffers de escrita. Não tem efeito para um fluxo em memória.
- close() None
Fecha o fluxo e libera o buffer subjacente. Operações adicionais em um fluxo fechado levantam
ValueError.
- getvalue() str
Retorna o conteúdo atual do buffer subjacente.
- class io.BytesIO(string: bytes = b'')¶
Objeto semelhante a arquivo em memória para entrada/saída em modo binário (similar a um arquivo normal aberto com o modificador “b”). O conteúdo inicial pode ser especificado com o parâmetro string (que deve ser um objeto bytes). As instâncias também suportam o protocolo de gerenciador de contexto (utilizável em uma instrução
with).- read(size: int = -1) bytes¶
Lê e retorna até size bytes. Se size for omitido ou negativo, lê e retorna todo o conteúdo restante.
- readline(size: int = -1) bytes¶
Lê e retorna uma linha. Se size for fornecido, no máximo size bytes são lidos.
- readinto(buf: bytearray) int¶
Lê para o buffer gravável pré-alocado buf e retorna o número de bytes lidos.
- seek(offset: int, whence: int = 0) int¶
Altera a posição do fluxo para offset relativo a whence (
0= início,1= atual,2= fim) e retorna a nova posição absoluta.
- close() None¶
Fecha o fluxo e libera o buffer subjacente. Operações adicionais em 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 a escrita de até essa quantidade de bytes não 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 nível de sistema, não para aplicações de usuário final.Diferença em relação ao CPython
Este construtor é uma extensão do MicroPython.
- read(size: int = -1) bytes
Lê e retorna até size bytes. Se size for omitido ou negativo, lê e retorna todo o conteúdo restante.
- readline(size: int = -1) bytes
Lê e retorna uma linha. Se size for fornecido, no máximo size bytes são lidos.
- readinto(buf: bytearray) int
Lê para o buffer gravável pré-alocado buf e retorna o número de bytes lidos.
- seek(offset: int, whence: int = 0) int
Altera a posição do fluxo para offset relativo a whence (
0= início,1= atual,2= fim) e retorna a nova posição absoluta.
- tell() int
Retorna a posição atual do fluxo.
- flush() None
Descarrega os buffers de escrita. Não tem efeito para um fluxo em memória.
- close() None
Fecha o fluxo e libera o buffer subjacente. Operações adicionais em um fluxo fechado levantam
ValueError.
- getvalue() bytes
Retorna o conteúdo atual do buffer subjacente.