O módulo `io` em Python
Este artigo explica o módulo io em Python.
Vamos explicar o módulo io em Python com exemplos práticos.
YouTube Video
O módulo io em Python
O processamento de entrada/saída forma a base para todos os tipos de operações de dados, como arquivos, redes e I/O padrão. O módulo io do Python fornece um conjunto de classes abstratas que unificam essas operações de entrada/saída. O conceito-chave para entender este módulo é a ideia de um "fluxo" (stream).
O que é um stream?
Um fluxo é um canal abstrato para leitura e escrita de dados de forma sequencial e contínua.
Ao ler conteúdos de arquivos byte a byte ou enviar e receber dados por uma rede, tudo isso pode ser tratado como fluxos de dados.
Ao abstrair esse mecanismo, arquivos, memória e redes—diferentes fontes de E/S—podem ser manipulados com operações comuns, como ler e escrever.
O módulo io do Python fornece uma interface unificada para fluxos, permitindo o tratamento eficiente de dados textuais e binários.
Estrutura básica do módulo io
O módulo io tem uma hierarquia de três camadas de acordo com a natureza dos fluxos.
-
Camada Bruta (
RawIOBase)RawIOBaselida com a E/S de bytes em nível mais baixo, como descritores de arquivos do sistema operacional e dispositivos. -
Camada com Buffer (
BufferedIOBase)BufferedIOBasefornece um cache (buffer) para melhorar a eficiência da E/S.BufferedReadereBufferedWritersão exemplos típicos. -
Camada de Texto (
TextIOBase)TextIOBaseconverte sequências de bytes em strings e lida com codificações. Normalmente, ao abrir um arquivo com a funçãoopen(), oTextIOWrapperdesta camada é utilizado.
Graças a esta estrutura, o módulo io separa claramente E/S de texto e binária, permitindo combinações flexíveis.
Estrutura básica do módulo io
RawIOBase lida com descritores de arquivos do SO na camada mais baixa, com BufferedIOBase adicionando um cache acima, e a camada superior TextIOBase cuidando da conversão de strings.
1import io
2
3# Check the core base classes hierarchy
4print(io.IOBase.__subclasses__())- Este código serve para verificar o grupo de classes abstratas que herdam de
IOBase. É possível verTextIOBase,BufferedIOBaseeRawIOBase, confirmando a estrutura hierárquica.
io.IOBase: A classe base de todas
IOBase é a classe base abstrata de todos os objetos de E/S, definindo métodos comuns como close(), flush() e seekable(). Ela é raramente utilizada diretamente, sendo normalmente acessada por meio de classes derivadas.
1import io
2
3f = io.StringIO("data")
4print(f.seekable()) # True
5print(f.readable()) # True
6print(f.writable()) # True
7f.close()- Este exemplo mostra que os métodos comuns de
IOBasetambém podem ser usados nas classes superiores.seekable()ereadable()são úteis para verificar as propriedades de um fluxo.
io.RawIOBase: A camada de menor nível
RawIOBase é a camada mais próxima do descritor de arquivos do SO e não faz cache de dados (buffering). A implementação típica é o FileIO, que lê e escreve byte a byte.
1import io, os
2
3# Create a low-level FileIO object (no buffering)
4fd = os.open('raw_demo.bin', os.O_RDWR | os.O_CREAT)
5raw = io.FileIO(fd, mode='w+')
6raw.write(b'abc123')
7raw.seek(0)
8print(raw.read(6)) # b'abc123'
9raw.close()FileIOé uma implementação concreta deRawIOBase; todas as leituras e escritas são realizadas comobytes. A eficiência pode ser melhorada ao combiná-lo com a camada superiorBufferedIOBase.
io.BufferedIOBase: Camada intermediária (com buffer)
BufferedIOBase é uma camada intermediária que realiza buffering, tornando o acesso ao disco mais eficiente. As principais implementações são BufferedReader, BufferedWriter, BufferedRandom e BufferedRWPair.
1import io
2
3# Create a buffered binary stream on top of a BytesIO (simulate file)
4base = io.BytesIO()
5buffered = io.BufferedWriter(base)
6buffered.write(b'Python IO buffering')
7buffered.flush()
8base.seek(0)
9print(base.read()) # b'Python IO buffering'- Neste exemplo, dados escritos via
BufferedWritersão temporariamente armazenados em um buffer na memória e são realmente transferidos para a camada inferior ao chamarflush().
Exemplo de BufferedReader
BufferedReader é um fluxo em buffer somente leitura que suporta leitura eficiente com peek() e read().
1import io
2
3stream = io.BytesIO(b"1234567890")
4reader = io.BufferedReader(stream)
5print(reader.peek(5)) # b'12345' (non-destructive)
6print(reader.read(4)) # b'1234'
7print(reader.read(3)) # b'567'peek()apenas "espia" os dados e não move o ponteiro. Ao combiná-lo comread(), você pode controlar o buffer de forma flexível.
io.TextIOBase: Camada exclusiva de texto
TextIOBase é uma camada de abstração para manipulação de strings, realizando internamente decodificação e codificação. Uma classe de implementação típica é TextIOWrapper.
1import io
2
3# Wrap a binary stream to handle text encoding
4binary = io.BytesIO()
5text_stream = io.TextIOWrapper(binary, encoding='utf-8')
6text_stream.write("\u3053\u3093\u306B\u3061\u306F")
7text_stream.flush()
8
9# Reset stream position
10binary.seek(0)
11
12# Read bytes once
13data = binary.read()
14
15# Show both raw bytes and decoded text
16print("Raw bytes:", data)
17print("Decoded text:", data.decode('utf-8'))- Neste exemplo,
TextIOWrappercodifica a string em UTF-8 e a escreve no fluxo binário subjacente.
Exemplo de leitura com TextIOWrapper
A decodificação é feita automaticamente ao ler.
1import io
2
3binary_data = io.BytesIO("Python I/O".encode('utf-8'))
4text_reader = io.TextIOWrapper(binary_data, encoding='utf-8')
5print(text_reader.read()) # 'Python I/O'TextIOWrapperserve como classe fundamental para E/S de texto e é a base para quase todas as operações de arquivos em alto nível.
io.StringIO: Fluxo de texto em memória
StringIO é uma classe que permite manipular strings em memória como se fossem arquivos. É útil para testes de E/S e geração de dados temporários.
1import io
2
3text_buf = io.StringIO()
4text_buf.write("In-memory text stream")
5text_buf.seek(0)
6print(text_buf.read()) # 'In-memory text stream'StringIOpermite operações do tipo arquivo sem usar o disco e é amplamente utilizado em testes unitários.
io.BytesIO: Fluxo binário em memória
BytesIO é uma classe de arquivo em memória para manipular sequências de bytes (bytes). É útil para situações como processamento binário ou compressão de dados onde você não deseja utilizar arquivos.
1import io
2
3buf = io.BytesIO()
4buf.write(b'\x01\x02\x03')
5buf.seek(0)
6print(list(buf.read())) # [1, 2, 3]BytesIOpossui a mesma interface deBufferedIOBasee pode ser usado como substituto para muitas APIs de arquivo.
Fluxos personalizados (criando classes originais)
As classes em io são extensíveis, permitindo que você crie suas próprias classes de fluxo. Abaixo está um exemplo de uma subclasse de TextIOBase que transforma todo o texto em maiúsculas ao escrever.
1import io
2
3class UpperTextIO(io.TextIOBase):
4 def __init__(self):
5 self.buffer = ""
6 def write(self, s):
7 self.buffer += s.upper()
8 return len(s)
9
10u = UpperTextIO()
11u.write("hello io")
12print(u.buffer) # "HELLO IO"- Desde que siga o contrato de
TextIOBase, você pode definir qualquer comportamento personalizado assim. Também é fácil expandir fluxos para usos específicos, como arquivos e redes.
Resumo
O módulo io organiza o processamento de entrada/saída em uma hierarquia de classes abstratas e concretas.
RawIOBaseé uma classe para E/S de bytes em nível de SO.BufferedIOBaseé uma classe que fornece uma camada de cache eficiente.TextIOBaseé uma classe que gerencia a leitura e escrita de strings.StringIOeBytesIOsão classes que fornecem fluxos em memória.
Compreender essas classes permite entender precisamente o funcionamento do sistema de E/S do Python e aplicá-las a operações de arquivos, comunicação em rede e design de fluxos de teste.
Você pode acompanhar o artigo acima usando o Visual Studio Code em nosso canal do YouTube. Por favor, confira também o canal do YouTube.