Python中bytearray对象赋值文件内容后变为不可变bytes对象的原因及解决方法
问题原因与解决办法
你踩的这个坑其实很常见——变量赋值把原来的bytearray对象给覆盖了,不是bytearray本身有问题。
先给你拆解一下问题:
你一开始把raw_data初始化成了bytearray(),这时候它确实是可变的bytearray类型。但当你执行raw_data = f.read()的时候,f.read()返回的是不可变的bytes对象,这行代码相当于把raw_data这个变量重新指向了这个新的bytes对象,原来那个空的bytearray就被彻底抛弃了。所以之后你尝试修改raw_data[0]时,自然会触发TypeError——因为现在它指向的是不可变的bytes,不是你一开始创建的bytearray。
解决办法(两种思路)
1. 直接将文件内容转为bytearray(简单高效)
不用先初始化空的bytearray,直接把f.read()的结果转成bytearray,一步到位:
raw_data = bytearray() try: with open(input_file, "rb") as f: raw_data = bytearray(f.read()) # 直接把bytes转成bytearray except IOError: print('Error opening', input_file) raw_data[0] = 55 # 现在可以正常修改第一个字节了
2. 分块写入原bytearray(适合大文件,节省内存)
如果你的文件很大,不想一次性读入全部内容到内存,可以用extend()方法把读取的bytes块添加到原来的bytearray里,这样就不会覆盖原对象:
raw_data = bytearray() try: with open(input_file, "rb") as f: chunk = f.read(4096) # 每次读取4KB的块,可根据需求调整大小 while chunk: raw_data.extend(chunk) # 将bytes块追加到bytearray中 chunk = f.read(4096) except IOError: print('Error opening', input_file) raw_data[0] = 55
这种方式下,raw_data自始至终都是bytearray类型,完全符合你想直接在原对象上修改的需求。
补充说明
要区分变量赋值和对象修改:
raw_data = f.read()是给变量重新赋值,让它指向新的对象;- 而
raw_data.extend(chunk)才是修改原来的bytearray对象本身,不会改变变量的指向。
内容的提问来源于stack exchange,提问作者CugelTC
相关产品推荐
相关产品推荐

