Python3中bytearray的使用问题请教

以前在 python2 中 a=bytes(bytearray((182,)))结果是 a=’\xb6’
现在在 Python3 运行结果是 a=b’\xb6’,尝试各种 a.decode()均失败了,请问如何能在 Python3 得到和 Python2 一样的结果呢?
Python3中bytearray的使用问题请教

6 回复

在Python3里,bytearray 是个可变(mutable)的字节序列,跟不可变的 bytes 对象是兄弟。它最大的特点就是能原地修改,这在处理二进制数据流或者网络协议时特别有用。

核心特性和常见用法:

  1. 创建:可以直接从整数列表、bytes对象、字符串(需指定编码)或者可迭代的整数创建。

    # 从整数列表创建
    ba = bytearray([65, 66, 67])  # bytearray(b'ABC')
    # 从bytes创建
    ba = bytearray(b'hello')
    # 从字符串创建
    ba = bytearray('你好', encoding='utf-8')
    
  2. 修改:像列表一样通过索引赋值、切片赋值、appendextend等方法修改。

    ba = bytearray(b'hello')
    ba[0] = 72  # 修改第一个字节,变成 bytearray(b'Hello')
    ba.append(33)  # 添加'!',变成 bytearray(b'Hello!')
    ba[1:3] = b'i'  # 切片替换,变成 bytearray(b'Hilo!')
    
  3. 与bytes互转bytearray可以直接当bytes用(很多函数接受bytes-like对象),也可以轻松转回bytes

    ba = bytearray(b'data')
    b = bytes(ba)  # 转成不可变的bytes对象
    

一个典型场景示例:处理一个简单的二进制数据包 假设数据包格式是:1字节类型 + 4字节长度 + N字节数据。

def parse_packet(packet_data):
    # packet_data 是 bytes 或 bytearray
    if len(packet_data) < 5:
        raise ValueError("Packet too short")
    
    # 使用 memoryview 避免切片复制,提升性能(特别是在大包时)
    mv = memoryview(packet_data)
    pkt_type = mv[0]
    # 将接下来的4个字节解释为小端序的整数
    data_len = int.from_bytes(mv[1:5], 'little')
    
    if len(packet_data) != 5 + data_len:
        raise ValueError("Packet length mismatch")
    
    data_section = mv[5:5+data_len]
    # 对 data_section 进行处理...
    # 因为使用了 memoryview,这里不会产生数据复制
    
    return pkt_type, data_len, data_section.tobytes()  # 最后需要数据时再转成bytes

# 构建一个响应包(使用可变的bytearray就很方便)
def build_response_packet(resp_data):
    ba = bytearray()
    ba.append(0x01)  # 类型字段
    ba.extend(len(resp_data).to_bytes(4, 'little'))  # 长度字段
    ba.extend(resp_data)  # 数据字段
    return ba  # 返回 bytearray,如果需要不可变版本就 bytes(ba)

# 使用示例
raw_packet = b'\x02\x04\x00\x00\x00test'
try:
    t, l, d = parse_packet(raw_packet)
    print(f"Type: {t}, Length: {l}, Data: {d}")
except ValueError as e:
    print(f"Error: {e}")

response = build_response_packet(b'ok')
print(f"Response packet: {response}")

什么时候用bytearray? 当你需要频繁修改一个字节序列中间某部分,或者像构建数据包那样逐步组装二进制数据时,用bytearray比反复拼接bytes对象(每次都会产生新对象)更高效。如果数据不需要修改,直接用bytes更合适。

简单说就是:要改就用bytearray,不改就用bytes

  1. Python3 里面的 str 已经是 unicode str 了。
    2. bytes(bytearray((182,)))你用的就是 bytes 函数,所以理所当然的,无论 py2 还是 py3 都返回 bytes 类型,只不过 py2 时 bytes==str 而已。
    3. 如果你想得到的是 latin_1 编码的\xb6 代表的 str,请用.decode(‘latin-1’)

str(a)得到的是’‘b’\xb6’ ''😹

再请教一下,在 Python2 和 Python3 中用 chr()函数出的结果不一样,有什么替代方案吗

如果你要的是 unicode str,那就是 chr(250),如果你要的是 latin-1 格式编码,那就是 chr(250).encode(‘latin-1’)

回到顶部