Python StringIO 模块
In-memory file objects for testing and for APIs that expect a file handle.
Key Points`StringIO` lets you treat a string as a file — perfect for parsing CSV text or faking a file in tests.
Basics
It implements the same read/write/seek interface as open(), so anything that takes a file object accepts it.
Python
from io import StringIO
buf = StringIO()
buf.write("name,age\n")
buf.write("alice,30\n")
print(buf.getvalue())
buf.seek(0) # 读之前必须回到开头
print(buf.readline().strip())Output
name,age
alice,30
name,ageParsing CSV from a String
csv.DictReader wants a file object. Wrap a string in StringIO and the whole csv API works.
Python
import csv
from io import StringIO
raw = "name,age\nalice,30\nbob,25\n"
rows = list(csv.DictReader(StringIO(raw)))
print(rows)Output
[{'name': 'alice', 'age': '30'}, {'name': 'bob', 'age': '25'}]BytesIO
The binary version — feed an uploaded image to Pillow, or build a zip in memory for a response, without touching disk.
Python
from io import BytesIO
from PIL import Image
buf = BytesIO()
Image.new("RGB", (10, 10), "red").save(buf, "PNG")
print(len(buf.getvalue()) > 0)
buf.seek(0)
img = Image.open(buf)
print(img.size, img.mode)Output
True
(10, 10) RGBForgetting
seek(0) is the classic bug — reading right after writing returns empty because the pointer is at the end.基础用法
它实现了和 open() 返回对象一样的 read/write/seek 接口,所以任何「接收文件对象」的函数都能直接吃它。
Python
from io import StringIO
buf = StringIO()
buf.write("name,age\n")
buf.write("alice,30\n")
print(buf.getvalue())
buf.seek(0) # 读之前必须回到开头
print(buf.readline().strip())Output
name,age
alice,30
name,age从字符串解析 CSV
csv.DictReader 需要文件对象。拿到的是字符串(比如接口返回)时,套一层 StringIO 就能复用整套 csv 逻辑。
Python
import csv
from io import StringIO
raw = "name,age\nalice,30\nbob,25\n"
rows = list(csv.DictReader(StringIO(raw)))
print(rows)Output
[{'name': 'alice', 'age': '30'}, {'name': 'bob', 'age': '25'}]BytesIO
二进制版本。上传的图片要送进 Pillow、要生成 zip 返回给前端,都走 BytesIO,全程不落磁盘。
Python
from io import BytesIO
from PIL import Image
buf = BytesIO()
Image.new("RGB", (10, 10), "red").save(buf, "PNG")
print(len(buf.getvalue()) > 0)
buf.seek(0)
img = Image.open(buf)
print(img.size, img.mode)Output
True
(10, 10) RGB忘了
seek(0) 是最常见的坑:写完直接读会得到空字符串,因为指针在末尾。