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

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

Abre um arquivo. A função interna open() é um alias para esta função. O parâmetro mode é sempre suportado; o suporte a outros argumentos pode variar.

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, 0 no fim do fluxo, ou None se 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 None se 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 valor errno negativo 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 bytes para fluxos binários e str para 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 / str vazio no fim do fluxo.

readlines() list

Lê até o fim do fluxo e retorna uma list de 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 (ou ValueError para 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. Levanta OSError em um fluxo que não permite reposicionamento.

tell() int

Retorna a posição absoluta atual no fluxo. Equivalente a seek(0, 1).

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ão with 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_obj e mp_stream_write1_obj que 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 como machine.UART para implementar seus próprios read / write – mas nenhuma classe de fluxo padrão os vincula como métodos read1 / readinto1 / write1 chamá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.

write(s: str) int

Escreve a string s e retorna o número de caracteres escritos.

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

Cria um objeto StringIO vazio 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.

write(s: str) int

Escreve a string s e retorna o número de caracteres escritos.

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.

write(b: bytes) int

Escreve o objeto semelhante a bytes b e retorna o número de bytes escritos.

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.

class io.BytesIO(alloc_size: int)

Cria um objeto BytesIO vazio 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.

write(b: bytes) int

Escreve o objeto semelhante a bytes b e retorna o número de bytes escritos.

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.