哈夫曼压缩工具调用but_decomp时报decompress缺失input_path参数错误
错误原因
- 直接触发报错的原因:你定义的
HuffmanCoding.decompress()方法明确要求传入input_path参数,但你在but_decomp方法中调用该方法时没有传入任何参数,因此触发了参数缺失的TypeError。 - 隐藏逻辑缺陷:你当前的哈夫曼编码类设计中,解压必需的反向映射表
reverse_mapping是压缩过程中生成的实例属性,没有存入压缩后的.bin文件。解压时新建的HuffmanCoding实例没有对应映射表,就算解决参数报错也无法正常完成解压。
解决方案
第一步:修复参数报错
将decompress方法的入参改为直接使用实例初始化时传入的路径,修改代码如下:
# 原定义:def decompress(self, input_path): # 修改为: def decompress(self): filename, file_extension = os.path.splitext(self.path) output_path = filename + "_decompressed" + ".txt" # 原代码:with open(input_path, 'rb') as file, open(output_path, 'w') as output: # 修改为: with open(self.path, 'rb') as file, open(output_path, 'w') as output: # 剩余原有逻辑不变
调用处的H.decompress()不需要修改,此时参数报错会消失。
第二步:修复解压逻辑(实现正常解压)
你需要将压缩时生成的频率表存入.bin文件头部,解压时先读取频率表重建哈夫曼树和映射表,修改逻辑如下:
- 导入json模块用于序列化频率表:
import json
- 修改
compress方法,写入频率表到文件头部:
def compress(self): filename, file_extension = os.path.splitext(self.path) output_path = filename + ".bin" with open(self.path, 'r+') as file, open(output_path, 'wb') as output: text = file.read() text = text.rstrip() frequency = self.make_frequency_dict(text) # 序列化频率表为字节 freq_json = json.dumps(frequency).encode('utf-8') # 写入4字节的头部长度标记 output.write(len(freq_json).to_bytes(4, byteorder='big')) # 写入频率表头部 output.write(freq_json) self.make_heap(frequency) self.merge_nodes() self.make_codes() encoded_text = self.get_encoded_text(text) padded_encoded_text = self.pad_encoded_text(encoded_text) b = self.get_byte_array(padded_encoded_text) output.write(bytes(b)) print("Compressed") return output_path
- 修改
decompress方法,先读取头部重建映射表:
def decompress(self): filename, file_extension = os.path.splitext(self.path) output_path = filename + "_decompressed" + ".txt" with open(self.path, 'rb') as file, open(output_path, 'w') as output: # 先读4字节得到频率表长度 freq_len = int.from_bytes(file.read(4), byteorder='big') # 读取频率表并反序列化 freq_json = file.read(freq_len) frequency = json.loads(freq_json.decode('utf-8')) # 重建哈夫曼树和反向映射表 self.make_heap(frequency) self.merge_nodes() self.make_codes() bit_string = "" byte = file.read(1) while (len(byte) > 0): byte = ord(byte) bits = bin(byte)[2:].rjust(8, '0') bit_string += bits byte = file.read(1) encoded_text = self.remove_padding(bit_string) decompressed_text = self.decode_text(encoded_text) output.write(decompressed_text) print("Decompressed") return output_path
修改完成后,先选中.txt文件点击压缩生成.bin文件,再选中生成的.bin文件点击解压,即可正常得到解压后的文件。
内容的提问来源于stack exchange,提问作者Dr_Doritos
相关产品推荐
相关产品推荐

