You need to enable JavaScript to run this app. Python实现Movielens数据集下载、MD5校验及压缩包文件列表打印的代码优化
优惠活动
大模型
产品
解决方案
定价
更多

Python实现Movielens数据集下载、MD5校验及压缩包文件列表打印的代码优化

代码补全与优化方案

原有代码的核心问题

  • 变量定义顺序颠倒:下载校验文件时,checksum变量还未被赋值为本地存储路径,直接运行会触发NameError
  • 缺失MD5校验核心逻辑:没有实现本地文件哈希与官方校验值的比对流程
  • 校验值解析逻辑缺失:GroupLens提供的.md5文件格式为「<32位哈希值> <原文件名>」,无法直接读取全文与本地计算结果比对
  • 拼写错误:listOfiles遗漏字母f,代码可读性差
  • 无异常容错:网络失败、文件损坏、权限不足等场景会直接抛出原生栈信息,用户无法快速定位问题
补全校验逻辑的实现流程

整体流程严格遵循「先校验、再操作」的要求:

  1. 先定义所有本地存储的文件名常量,避免变量顺序错误
  2. 下载数据集压缩包与官方MD5校验文件
  3. 分块计算本地压缩包的MD5值
  4. 解析官方校验文件,提取有效32位哈希值
  5. 比对两个哈希值,一致则继续执行,不一致则清理损坏文件并退出
  6. 校验通过后,调用封装的print_zip_files函数读取并打印压缩包内的文件列表
优化后的可运行代码
from zipfile import ZipFile
from urllib import request
import hashlib
import os

# 提前定义所有固定常量,避免变量顺序错误
URL_DATASET = "http://files.grouplens.org/datasets/movielens/ml-25m.zip"
URL_MD5 = "http://files.grouplens.org/datasets/movielens/ml-25m.zip.md5"
LOCAL_DATASET = "ml-25m.zip"
LOCAL_MD5_FILE = "ml-25m.zip.md5"

def calculate_md5(file_path: str) -> str:
    """分块读取计算文件MD5,避免大文件占满内存"""
    hash_md5 = hashlib.md5()
    with open(file_path, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

def extract_official_md5(md5_file_path: str) -> str:
    """从官方MD5文件中提取有效哈希值,适配文件的标准格式"""
    with open(md5_file_path, "r", encoding="utf-8") as f:
        # 官方文件格式为 "哈希值  原文件名",拆分后取第一个元素即可
        return f.read().strip().split()[0]

def print_zip_files(zip_path: str):
    """校验通过后,读取并打印压缩包内的所有文件名"""
    with ZipFile(zip_path, "r") as zip_obj:
        file_list = zip_obj.namelist()
        for file_name in file_list:
            print(file_name)

if __name__ == "__main__":
    # 下载目标文件,增加异常捕获
    try:
        request.urlretrieve(URL_DATASET, LOCAL_DATASET)
        request.urlretrieve(URL_MD5, LOCAL_MD5_FILE)
    except Exception as e:
        print(f"文件下载失败:{str(e)}")
        exit(1)

    # 执行MD5校验
    local_calc_md5 = calculate_md5(LOCAL_DATASET)
    official_md5 = extract_official_md5(LOCAL_MD5_FILE)

    if local_calc_md5 != official_md5:
        print("MD5校验不通过,下载文件已损坏,请重新下载")
        # 自动清理损坏的无效文件
        if os.path.exists(LOCAL_DATASET):
            os.remove(LOCAL_DATASET)
        exit(1)

    print("MD5校验通过,压缩包包含以下文件:")
    print_zip_files(LOCAL_DATASET)
可进一步优化的方向
  • 增加重复下载判断:如果本地已存在对应文件,先计算本地MD5与官方值比对,一致则跳过下载流程,节省带宽
  • 增加下载进度提示:通过urlretrieve的reporthook参数实现下载进度条,提升大文件下载的交互体验
  • 替换为HTTPS请求:将原有HTTP地址替换为对应HTTPS地址,避免下载过程被篡改,提升安全性
  • 增加压缩包合法性校验:读取文件列表前先判断Zip对象是否正常,避免损坏的非zip文件触发解压错误
  • 优化文件存储逻辑:下载过程中先使用临时后缀(如.tmp)存储文件,校验通过后再重命名为正式文件名,避免用户提前访问未下载完成的文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 21:06:02