Modulen `io` i Python
Den här artikeln förklarar modulen io i Python.
Vi kommer att förklara modulen io i Python med praktiska exempel.
YouTube Video
Modulen io i Python
In- och utmatningshantering utgör grunden för alla typer av dataoperationer, såsom filer, nätverk och standard I/O. Pythons modul io tillhandahåller en uppsättning abstrakta klasser som förenar dessa in- och utmatningsoperationer. Det viktigaste konceptet för att förstå denna modul är idén om ett "flöde" (stream).
Vad är en ström?
Ett flöde är ett abstrakt sätt att läsa och skriva data sekventiellt och kontinuerligt.
När man läser filinnehåll byte för byte eller skickar och tar emot data över ett nätverk kan allt detta hanteras som dataströmmar.
Genom att abstrahera denna mekanism kan filer, minne och nätverk – olika källor till I/O – hanteras med gemensamma operationer såsom läsning och skrivning.
Pythons modul io tillhandahåller ett enhetligt gränssnitt för strömmar, vilket möjliggör effektiv hantering av både text och binär data.
Grundläggande struktur för modulen io
Modulen io har en trelagershierarki beroende på typen av strömmar.
-
Rått lager (
RawIOBase)RawIOBasehanterar den lägsta nivån för byte I/O, såsom operativsystemets fildeskriptorer och enheter. -
Buffrat lager (
BufferedIOBase)BufferedIOBasetillhandahåller en cache (buffert) för att öka I/O-effektiviteten.BufferedReaderochBufferedWriterär typiska exempel. -
Textlager (
TextIOBase)TextIOBasekonverterar byte-sekvenser till strängar och hanterar kodning (encoding). Vanligtvis, när man öppnar en fil med funktionenopen(), användsTextIOWrapperfrån detta lager.
Tack vare denna struktur separerar modulen io tydligt text- och binär-I/O samtidigt som flexibla kombinationer är möjliga.
Grundläggande struktur för modulen io
RawIOBase hanterar operativsystemets fildeskriptorer på den lägsta nivån, sedan lägger BufferedIOBase till en cache, och det översta lagret, TextIOBase, hanterar strängkonverteringar.
1import io
2
3# Check the core base classes hierarchy
4print(io.IOBase.__subclasses__())- Denna kod används för att kontrollera gruppen av abstrakta klasser som ärver från
IOBase. Du kan seTextIOBase,BufferedIOBaseochRawIOBase, vilket bekräftar den hierarkiska strukturen.
io.IOBase: Bas-klassen för alla
IOBase är den abstrakta basklassen för alla I/O-objekt och definierar gemensamma metoder såsom close(), flush() och seekable(). Den används sällan direkt och nås vanligtvis via subklasser.
1import io
2
3f = io.StringIO("data")
4print(f.seekable()) # True
5print(f.readable()) # True
6print(f.writable()) # True
7f.close()- Detta exempel visar att de gemensamma metoderna hos
IOBaseäven kan användas i högre liggande klasser.seekable()ochreadable()är användbara för att kontrollera egenskaperna hos en ström.
io.RawIOBase: Det lägsta lagret
RawIOBase är det lager som ligger närmast operativsystemets fildeskriptor och utför ingen buffring. Den typiska implementeringen är FileIO, som läser och skriver byte för 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är en konkret implementering avRawIOBase; all läsning och skrivning sker sombytes. Effektiviteten kan förbättras om man kombinerar det med det högre lagretBufferedIOBase.
io.BufferedIOBase: Mellanlager (med buffring)
BufferedIOBase är ett mellanlager som utför buffring, vilket gör diskåtkomst mer effektiv. De viktigaste implementeringarna är BufferedReader, BufferedWriter, BufferedRandom och 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 det här exemplet lagras data som skrivs via
BufferedWritertemporärt i en minnesbuffert och överförs faktiskt till det undre lagret när man anroparflush().
Exempel på BufferedReader
BufferedReader är en skrivskyddad buffrad ström som stöder effektiv läsning med peek() och 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()"kikar" bara på datan och flyttar inte pekaren. Genom att kombinera den medread()kan du flexibelt styra buffringen.
io.TextIOBase: Endast text-lager
TextIOBase är ett abstraktionslager för att hantera strängar, som internt utför avkodning och kodning. En typisk implementering är 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 det här exemplet kodar
TextIOWrappersträngen till UTF-8 och skriver den till den underliggande binära strömmen.
Exempel på läsning med TextIOWrapper
Dekodning sker automatiskt vid läsning.
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'TextIOWrapperfungerar som grundklassen för text-I/O och utgör basen för nästan alla avancerade filoperationer.
io.StringIO: Textström i minnet
StringIO är en klass som låter dig hantera strängar i minnet som om de vore filer. Den är användbar för I/O-testning och tillfällig 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'StringIOmöjliggör fil-liknande operationer utan att använda disken och används ofta i enhetstester.
io.BytesIO: Binärström i minnet
BytesIO är en minnesbaserad filklass för hantering av byte-sekvenser (bytes). Den är användbar för situationer som binärhantering eller datakomprimering där man inte vill använda filer.
1import io
2
3buf = io.BytesIO()
4buf.write(b'\x01\x02\x03')
5buf.seek(0)
6print(list(buf.read())) # [1, 2, 3]BytesIOhar samma gränssnitt somBufferedIOBaseoch kan användas som ersättning för många fil-API:er.
Egna strömmar (skapa egna klasser)
Klasserna i io är utbyggbara, vilket gör att du kan skapa egna strömklasser. Nedan finns ett exempel på en subklass till TextIOBase som skriver all text med versaler.
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å länge du följer kontraktet för
TextIOBasekan du definiera valfritt eget beteende på detta sätt. Det är också enkelt att utöka strömmar för särskilda ändamål, såsom filer och nätverk.
Sammanfattning
Modulen io organiserar in- och utmatningshantering i en hierarki av abstrakta och konkreta klasser.
RawIOBaseär en klass för byte-I/O på operativsystemnivå.BufferedIOBaseär en klass som tillhandahåller ett effektivt cache-lager.TextIOBaseär en klass som hanterar läsning och skrivning av strängar.StringIOochBytesIOär klasser som tillhandahåller minnesströmmar.
Genom att förstå dessa klasser kan du noggrant förstå hur Pythons I/O-system fungerar och tillämpa dem på filoperationer, nätverkskommunikation och design av testströmmar.
Du kan följa med i artikeln ovan med hjälp av Visual Studio Code på vår YouTube-kanal. Vänligen kolla även in YouTube-kanalen.