Modulen `io` i Python

Modulen `io` i Python

Denne artikkelen forklarer modulen io i Python.

Vi vil forklare modulen io i Python med praktiske eksempler.

YouTube Video

Modulen io i Python

Inndata/utdata-behandling danner grunnlaget for alle typer dataoperasjoner, som filer, nettverk og standard I/O. Pythons modul io tilbyr et sett med abstrakte klasser som forener disse inn-/utdata-operasjonene. Hovedkonseptet for å forstå denne modulen er ideen om en "strøm" (stream).

Hva er en strøm?

En strøm er en abstrakt flyt for å lese og skrive data sekvensielt og kontinuerlig.

Når man leser filinnhold byte for byte eller sender og mottar data over et nettverk, kan alt dette håndteres som datastrømmer.

Ved å abstrahere denne mekanismen kan filer, minne og nettverk – ulike kilder til I/O – håndteres med felles operasjoner som lesing og skriving.

Pythons modul io tilbyr et enhetlig grensesnitt for strømmer, noe som muliggjør effektiv håndtering av både tekst og binære data.

Grunnleggende struktur i modulen io

Modulen io har et tre-lags hierarki i henhold til strømmenes natur.

  1. Rå-lag (RawIOBase)

    RawIOBase håndterer de laveste nivåene av byte-I/O, som OS-filbeskrivelser og enheter.

  2. Buffret lag (BufferedIOBase)

    BufferedIOBase gir en buffer for å forbedre I/O-effektiviteten. BufferedReader og BufferedWriter er typiske eksempler.

  3. Tekstlag (TextIOBase)

    TextIOBase konverterer bytesevenser til strenger og håndterer koding. Vanligvis, når du åpner en fil med funksjonen open(), benyttes TextIOWrapper fra dette laget.

Takket være denne strukturen skiller modulen io tydelig mellom tekst- og binær-I/O, samtidig som den tillater fleksible kombinasjoner.

Grunnleggende struktur i modulen io

RawIOBase håndterer OS-filbeskrivelser på det laveste laget, med BufferedIOBase som legger til en buffer, og det øverste laget TextIOBase som håndterer strengkonverteringer.

1import io
2
3# Check the core base classes hierarchy
4print(io.IOBase.__subclasses__())
  • Denne koden er for å sjekke gruppen av abstrakte klasser som arver fra IOBase. Du kan se TextIOBase, BufferedIOBase og RawIOBase, noe som bekrefter den hierarkiske strukturen.

io.IOBase: Grunnklassen for alle

IOBase er den abstrakte grunnklassen for alle I/O-objekter, og definerer felles metoder som close(), flush() og seekable(). Den brukes sjelden direkte og benyttes vanligvis via avledede klasser.

1import io
2
3f = io.StringIO("data")
4print(f.seekable())   # True
5print(f.readable())   # True
6print(f.writable())   # True
7f.close()
  • Dette eksempelet viser at de felles metodene i IOBase også kan brukes i de øvre klassene. seekable() og readable() er nyttige for å sjekke egenskapene til en strøm.

io.RawIOBase: Det laveste laget

RawIOBase er laget nærmest OS-filbeskrivelsen og utfører ikke buffering. Den typiske implementasjonen er FileIO, som leser og skriver byte for 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 er en konkret implementasjon av RawIOBase; all lesing og skriving gjøres som bytes. Effektiviteten kan forbedres ved å kombinere den med det øvre laget BufferedIOBase.

io.BufferedIOBase: Mellomlag (med buffering)

BufferedIOBase er et mellomlag som utfører buffering, og gjør disktilgang mer effektiv. Hovedimplementasjonene er BufferedReader, BufferedWriter, BufferedRandom og 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'
  • I dette eksempelet blir data skrevet via BufferedWriter midlertidig lagret i en minnebuffer, og overføres faktisk til det nedre laget ved kall av flush().

Eksempel på BufferedReader

BufferedReader er en skrivebeskyttet buffret strøm som støtter effektiv lesing med peek() og 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() bare "kikker" på dataene og flytter ikke pekerposisjonen. Ved å kombinere det med read() kan du fleksibelt kontrollere buffringen.

io.TextIOBase: Kun tekst-lag

TextIOBase er et abstraksjonslag for håndtering av strenger, som internt utfører dekoding og koding. En typisk implementeringsklasse er 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'))
  • I dette eksempelet koder TextIOWrapper strengen til UTF-8 og skriver den til den underliggende binærstrømmen.

Eksempel på lesing med TextIOWrapper

Dekoding skjer automatisk ved lesing.

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'
  • TextIOWrapper fungerer som den grunnleggende klassen for tekst-I/O og danner grunnlaget for nesten alle høynivå filoperasjoner.

io.StringIO: Tekststrøm i minnet

StringIO er en klasse som lar deg behandle strenger i minnet som om de var filer. Den er nyttig for I/O-testing og midlertidig datagenerering.

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'
  • StringIO gjør det mulig å utføre fil-lignende operasjoner uten å bruke harddisken, og brukes mye i enhetstesting.

io.BytesIO: Binær strøm i minnet

BytesIO er en i-minnet-filklasse for håndtering av bytesevenser (bytes). Den er nyttig i situasjoner som binærprosessering eller datakomprimering der du ikke ønsker å bruke filer.

1import io
2
3buf = io.BytesIO()
4buf.write(b'\x01\x02\x03')
5buf.seek(0)
6print(list(buf.read()))  # [1, 2, 3]
  • BytesIO har samme grensesnitt som BufferedIOBase og kan brukes som erstatning for mange fil-API-er.

Egendefinerte strømmer (lage egne klasser)

Klassene i io er utvidbare, slik at du kan lage dine egne strømklasser. Nedenfor er et eksempel på en underklasse av TextIOBase som gjør all tekst til store bokstaver ved skriving.

 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"
  • Så lenge du følger kontrakten til TextIOBase, kan du definere hvilken som helst egendefinert oppførsel som dette. Det er også enkelt å utvide strømmer for spesifikke bruksområder, som filer og nettverk.

Sammendrag

Modulen io organiserer inn- og utdata-prosessering i et hierarki av abstrakte og konkrete klasser.

  • RawIOBase er en klasse for byte-I/O på OS-nivå.
  • BufferedIOBase er en klasse som gir et effektivt bufferlag.
  • TextIOBase er en klasse som håndterer lesing og skriving av strenger.
  • StringIO og BytesIO er klasser som gir strømmer i minnet.

Å forstå disse klassene gjør at du nøyaktig kan forstå hvordan Pythons I/O-system fungerer, og bruke dem i filoperasjoner, nettverkskommunikasjon og utforming av teststrømmer.

Du kan følge med på artikkelen ovenfor ved å bruke Visual Studio Code på vår YouTube-kanal. Vennligst sjekk ut YouTube-kanalen.

YouTube Video