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

Python带数据目录的包:如何实现干净卸载?

问题根源

pip卸载时仅会删除安装过程中记录在包dist-info目录下RECORD文件里的文件,你动态生成的数据文件不在该记录中,因此会被判定为"手动添加"而保留。

解决方案

方案1:动态更新RECORD文件(让pip识别数据文件为包的一部分)

在生成数据文件后,手动将文件条目追加到RECORD中,让pip认为这些文件属于包的一部分,卸载时自动删除。

示例实现代码:

import os
import hashlib
from importlib.metadata import distribution

def add_files_to_record():
    # 获取包的分发信息
    dist = distribution("my_package")
    dist_root = dist.locate_file("")
    record_path = os.path.join(dist_root, f"{dist.metadata['Name']}-{dist.version}.dist-info", "RECORD")
    
    data_dir = os.path.join(os.path.dirname(__file__), "data")
    if not os.path.exists(data_dir):
        return
    
    # 遍历数据目录并写入RECORD
    with open(record_path, "a", encoding="utf-8") as record_file:
        for root, _, files in os.walk(data_dir):
            for file in files:
                file_abspath = os.path.join(root, file)
                file_relpath = os.path.relpath(file_abspath, dist_root)
                
                # 计算文件哈希和大小
                with open(file_abspath, "rb") as f:
                    hash_str = hashlib.sha256(f.read()).hexdigest()
                file_size = os.path.getsize(file_abspath)
                
                # 写入RECORD格式条目
                record_file.write(f"{file_relpath},sha256={hash_str},{file_size}\n")

在数据文件生成完成后调用该函数即可。注意:包更新时RECORD会被覆盖,需重新执行添加逻辑。

方案2:自定义卸载清理脚本(扩展setuptools命令)

通过setuptools自定义卸载命令,在原生卸载逻辑执行完成后自动清理数据目录。

  1. 创建包内清理模块my_package/uninstall_cleanup.py:
from setuptools.command.uninstall import uninstall as BaseUninstall
import os
import shutil

class CustomUninstall(BaseUninstall):
    def run(self):
        # 先执行原生卸载流程
        super().run()
        # 清理数据目录
        pkg_dir = os.path.dirname(os.path.abspath(__file__))
        data_dir = os.path.join(pkg_dir, "data")
        if os.path.exists(data_dir):
            shutil.rmtree(data_dir)
  1. 在pyproject.toml中配置自定义命令:
[tool.setuptools]
cmdclass = { uninstall = "my_package.uninstall_cleanup.CustomUninstall" }

注意:部分pip版本可能优先使用自身卸载逻辑,需测试兼容性。

方案3:将数据文件存储到用户目录(推荐最佳实践)

避免修改包目录,将数据文件存到系统默认的用户数据目录,同时提供清理命令让用户手动删除,更符合Python包设计规范。

  1. 使用appdirs库获取用户数据目录(需将appdirs添加到包依赖):
import appdirs
import os

data_dir = appdirs.user_data_dir("my_package")
os.makedirs(data_dir, exist_ok=True)
# 生成数据文件到该目录
  1. 在pyproject.toml中添加清理命令:
[project.scripts]
my-package-cleanup = "my_package.cleanup:main"
  1. 创建清理模块my_package/cleanup.py:
import appdirs
import shutil
import os

def main():
    data_dir = appdirs.user_data_dir("my_package")
    if os.path.exists(data_dir):
        shutil.rmtree(data_dir)
        print("数据文件已清理")
    else:
        print("无数据文件需要清理")

用户卸载包后,可运行my-package-cleanup命令删除数据文件。

关于pyproject.toml的直接支持

目前pyproject.toml本身没有原生配置卸载自动清理的字段,上述方案1、2需结合代码与pyproject.toml配置实现,方案3是更推荐的规范做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:00:41