Mô-đun `io` trong Python
Bài viết này giải thích về mô-đun io trong Python.
Chúng tôi sẽ giải thích mô-đun io trong Python với các ví dụ thực tế.
YouTube Video
Mô-đun io trong Python
Xử lý nhập/xuất là nền tảng cho mọi loại thao tác dữ liệu, như tệp, mạng và I/O tiêu chuẩn. Mô-đun io của Python cung cấp một tập hợp các lớp trừu tượng thống nhất các thao tác nhập/xuất này. Khái niệm then chốt để hiểu mô-đun này là ý tưởng về "luồng dữ liệu".
Luồng là gì?
Luồng là một dòng trừu tượng để đọc và ghi dữ liệu một cách tuần tự và liên tục.
Khi đọc nội dung tệp từng byte hoặc gửi và nhận dữ liệu qua mạng, tất cả đều có thể được xử lý như các luồng dữ liệu.
Bằng cách trừu tượng hóa cơ chế này, tệp, bộ nhớ và mạng—các nguồn I/O khác nhau—có thể được xử lý bằng các thao tác chung như đọc và ghi.
Mô-đun io của Python cung cấp một giao diện thống nhất cho các luồng, cho phép xử lý hiệu quả cả dữ liệu văn bản và dữ liệu nhị phân.
Cấu trúc cơ bản của mô-đun io
Mô-đun io có cấu trúc phân cấp ba lớp dựa trên đặc điểm của các luồng.
-
Lớp thô (
RawIOBase)RawIOBasexử lý I/O byte ở cấp thấp nhất, như mô tả tệp của hệ điều hành và thiết bị. -
Lớp bộ đệm (
BufferedIOBase)BufferedIOBasecung cấp bộ nhớ đệm để nâng cao hiệu suất I/O.BufferedReadervàBufferedWriterlà những ví dụ điển hình. -
Lớp văn bản (
TextIOBase)TextIOBasechuyển đổi chuỗi byte thành chuỗi ký tự và xử lý mã hóa. Thông thường, khi mở tệp bằng hàmopen(), lớpTextIOWrappertừ lớp này sẽ được sử dụng.
Nhờ cấu trúc này, mô-đun io phân tách rõ ràng giữa I/O văn bản và nhị phân, đồng thời cho phép kết hợp linh hoạt.
Cấu trúc cơ bản của mô-đun io
RawIOBase xử lý mô tả tệp của hệ điều hành ở lớp thấp nhất, BufferedIOBase bổ sung bộ nhớ đệm và lớp cao nhất TextIOBase xử lý chuyển đổi chuỗi.
1import io
2
3# Check the core base classes hierarchy
4print(io.IOBase.__subclasses__())- Đoạn mã này dùng để kiểm tra nhóm các lớp trừu tượng kế thừa từ
IOBase. Bạn có thể thấyTextIOBase,BufferedIOBase, vàRawIOBase, xác nhận cấu trúc phân cấp.
io.IOBase: Lớp cơ sở của tất cả
IOBase là lớp trừu tượng cơ sở cho tất cả các đối tượng I/O, định nghĩa các phương thức chung như close(), flush(), và seekable(). Nó hiếm khi được sử dụng trực tiếp và thường được truy cập thông qua các lớp dẫn xuất.
1import io
2
3f = io.StringIO("data")
4print(f.seekable()) # True
5print(f.readable()) # True
6print(f.writable()) # True
7f.close()- Ví dụ này cho thấy các phương thức chung của
IOBasecũng có thể được sử dụng ở các lớp cao hơn.seekable()vàreadable()hữu ích để kiểm tra các thuộc tính của một luồng dữ liệu.
io.RawIOBase: Lớp cấp thấp nhất
RawIOBase là lớp gần nhất với mô tả tệp của hệ điều hành và không sử dụng bộ nhớ đệm. Triển khai điển hình là FileIO, đọc và ghi theo từng 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()FileIOlà một triển khai cụ thể củaRawIOBase; tất cả hoạt động đọc và ghi đều thực hiện dưới dạngbytes. Hiệu suất có thể được nâng cao khi kết hợp với lớpBufferedIOBasephía trên.
io.BufferedIOBase: Lớp trung gian (có bộ đệm)
BufferedIOBase là lớp trung gian thực hiện bộ nhớ đệm, giúp truy cập ổ đĩa hiệu quả hơn. Các triển khai chính là BufferedReader, BufferedWriter, BufferedRandom, và 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'- Trong ví dụ này, dữ liệu được ghi qua
BufferedWritersẽ tạm thời được lưu trong bộ nhớ đệm và thực sự chuyển xuống lớp dưới khi gọiflush().
Ví dụ về BufferedReader
BufferedReader là một luồng bộ đệm chỉ đọc, hỗ trợ đọc hiệu quả với peek() và 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()chỉ "nhìn lướt" dữ liệu và không di chuyển con trỏ. Bằng cách kết hợp vớiread(), bạn có thể điều khiển bộ đệm một cách linh hoạt.
io.TextIOBase: Lớp chỉ dành cho văn bản
TextIOBase là một lớp trừu tượng để xử lý chuỗi, thực hiện giải mã và mã hóa bên trong. Một lớp triển khai tiêu biểu là 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'))- Trong ví dụ này,
TextIOWrappermã hóa chuỗi sang UTF-8 và ghi vào luồng nhị phân bên dưới.
Ví dụ đọc với TextIOWrapper
Giải mã được thực hiện tự động khi đọc.
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'TextIOWrapperlà lớp cơ bản cho I/O văn bản và tạo nền tảng cho hầu hết các thao tác tệp cấp cao.
io.StringIO: Luồng văn bản trong bộ nhớ
StringIO là một lớp cho phép bạn xử lý các chuỗi trong bộ nhớ như thể chúng là các tệp. Nó hữu ích cho kiểm thử I/O và tạo dữ liệu tạm thời.
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'StringIOcho phép thao tác giống như tệp mà không cần dùng đến ổ đĩa và thường được sử dụng trong kiểm thử đơn vị.
io.BytesIO: Luồng nhị phân trong bộ nhớ
BytesIO là một lớp tệp trong bộ nhớ để xử lý chuỗi byte (bytes). Nó hữu ích cho các tình huống như xử lý nhị phân hoặc nén dữ liệu khi bạn không muốn sử dụng tệp.
1import io
2
3buf = io.BytesIO()
4buf.write(b'\x01\x02\x03')
5buf.seek(0)
6print(list(buf.read())) # [1, 2, 3]BytesIOcó giao diện giống vớiBufferedIOBasevà có thể dùng thay thế cho nhiều API tệp.
Luồng tùy chỉnh (Tạo các lớp riêng)
Các lớp trong io có thể mở rộng, cho phép bạn tạo lớp luồng riêng của mình. Dưới đây là ví dụ về một lớp con của TextIOBase chuyển toàn bộ văn bản thành chữ in hoa khi ghi.
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"- Miễn là bạn tuân thủ các quy tắc của
TextIOBase, bạn có thể định nghĩa bất kỳ hành vi tùy chỉnh nào như vậy. Ngoài ra, cũng dễ dàng mở rộng luồng cho các mục đích cụ thể như tệp hoặc mạng.
Tóm tắt
Mô-đun io tổ chức xử lý nhập/xuất thành một hệ thống phân cấp gồm các lớp trừu tượng và cụ thể.
RawIOBaselà lớp dành cho I/O byte ở cấp hệ điều hành.BufferedIOBaselà lớp cung cấp lớp bộ đệm hiệu quả.TextIOBaselà lớp quản lý việc đọc và ghi chuỗi.StringIOvàBytesIOlà các lớp cung cấp luồng trong bộ nhớ.
Hiểu các lớp này giúp bạn nắm vững cách hoạt động của hệ thống I/O trong Python và áp dụng vào các thao tác tệp, giao tiếp mạng, cũng như thiết kế luồng kiểm thử.
Bạn có thể làm theo bài viết trên bằng cách sử dụng Visual Studio Code trên kênh YouTube của chúng tôi. Vui lòng ghé thăm kênh YouTube.