You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python2.7内存字符串gzip/gunzip工具迁移Python3求助

Python2.7 到 Python3 的 gzip/gunzip 迁移方案(解决 BytesIO/StringIO 适配问题)

在Python3里,字符串(str)和字节(bytes)是严格区分的,这也是你用io.StringIO没解决问题的核心原因——gzip操作的是二进制字节流,必须用BytesIO来处理,而不是处理文本的StringIO。下面是完整的迁移后的代码,我会逐点说明修改逻辑:

修改后的核心代码

from io import BytesIO
import gzip
import zlib

def str_to_gz_str(orig_text_str, mode='wb'):
    """
    @param orig_text_str: Original uncompressed text str
    @param mode: 'wb' default. 必须是二进制写入模式,因为gzip处理字节流
    @return compressed bytes(Python3中压缩结果是字节类型,而非字符串)
    """
    out = BytesIO()
    # 先把字符串编码成字节,再写入gzip流
    with gzip.GzipFile(fileobj=out, mode=mode) as f:
        f.write(orig_text_str.encode('utf-8'))
    return out.getvalue()

def gz_str_to_str(compressed_bytes):
    '''
    @param compressed_bytes: gzipped bytes(Python3中接收字节类型,而非字符串)
    @return decompressed string
    '''
    si = BytesIO(compressed_bytes)
    return gunzip_stream_to_str(si)

def gunzip_stream_to_str(gz_stream):
    '''
    decompress gz stream convert to string
    @param gz_stream: gzipped stream(BytesIO类型的字节流)
    @return decompressed str
    '''
    unzipped_bytes = b''
    # 先拼接字节,最后再解码成字符串
    for part in gunzip_stream(gz_stream):
        unzipped_bytes += part
    return unzipped_bytes.decode('utf-8')

def gunzip_stream(gz_stream):
    '''
    decompress gzipped stream
    @param gz_stream: src stream that is gzipped(BytesIO类型)
    @return yield decompressed byte chunks
    '''
    dec = zlib.decompressobj(16+zlib.MAX_WBITS)
    # gz_stream是BytesIO,迭代出来的chunk是字节类型
    for chunk in gz_stream:
        uz = dec.decompress(chunk)
        if uz:
            yield uz

修改点说明

  1. 导入替换:把from StringIO import StringIO换成from io import BytesIO,因为我们全程处理的是二进制字节流,而非文本流。
  2. 字符串转字节:在str_to_gz_str中,先把输入的orig_text_str用encode('utf-8')转成字节,再写入gzip流——Python3的gzip.GzipFile在二进制模式下只接受字节输入。
  3. 返回类型调整:压缩后的结果从Python2的“字节字符串”变成Python3的bytes类型,这是更严谨的类型区分。
  4. 解压后解码:在gunzip_stream_to_str中,先拼接解压出的字节片段,最后用decode('utf-8')转成字符串,还原原始文本。
  5. 模式参数默认值修改:把mode='w'改成mode='wb',因为gzip在Python3中默认如果用文本模式('w')会要求指定编码,而我们直接用二进制模式更符合gzip的使用场景。

测试代码(适配Python3)

txt_orig = "A Quick Brown fox"
txt_gz = str_to_gz_str(txt_orig)
# txt_gz现在是bytes类型,打印会显示b'...'
txt_decompr = gz_str_to_str(txt_gz)
assert(txt_orig == txt_decompr)
print("测试通过!")

运行这段测试代码,会成功通过断言,说明压缩和解压的逻辑完全正常。

内容的提问来源于stack exchange,提问作者sky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:36:17