本文目录导读:

我来为你提供一个自动清理Python缓存的脚本。
基础版本 - 清理Python缓存文件
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
自动清理Python缓存的脚本
"""
import os
import shutil
import sys
from pathlib import Path
def clean_python_cache(start_path="."):
"""
清理Python缓存文件
包括:__pycache__, .pyc, .pyo, .pyd, .egg-info, .egg
"""
deleted_count = 0
freed_space = 0
# 要删除的目录模式
dir_patterns = [
"__pycache__",
"*.egg-info",
"*.egg",
".mypy_cache",
".pytest_cache",
".hypothesis"
]
# 要删除的文件模式
file_patterns = [
"*.pyc",
"*.pyo",
"*.pyd",
"*.pyc.bak"
]
start_path = Path(start_path).resolve()
print(f"开始清理: {start_path}")
print("-" * 50)
for root, dirs, files in os.walk(start_path):
# 清理目录
for dir_name in dirs:
dir_path = os.path.join(root, dir_name)
for pattern in dir_patterns:
if pattern == dir_name or (pattern.startswith("*") and dir_name.endswith(pattern[1:])):
try:
size = get_folder_size(dir_path)
shutil.rmtree(dir_path)
deleted_count += 1
freed_space += size
print(f"删除目录: {dir_path} ({format_size(size)})")
except Exception as e:
print(f"删除目录失败 {dir_path}: {e}")
# 清理文件
for file_name in files:
file_path = os.path.join(root, file_name)
for pattern in file_patterns:
if file_name.endswith(pattern[1:]):
try:
size = os.path.getsize(file_path)
os.remove(file_path)
deleted_count += 1
freed_space += size
print(f"删除文件: {file_path} ({format_size(size)})")
except Exception as e:
print(f"删除文件失败 {file_path}: {e}")
print("-" * 50)
print(f"清理完成!")
print(f"删除项目数: {deleted_count}")
print(f"释放空间: {format_size(freed_space)}")
def get_folder_size(folder_path):
"""获取文件夹大小"""
total_size = 0
for dirpath, dirnames, filenames in os.walk(folder_path):
for f in filenames:
fp = os.path.join(dirpath, f)
try:
total_size += os.path.getsize(fp)
except:
pass
return total_size
def format_size(size_bytes):
"""格式化文件大小"""
if size_bytes == 0:
return "0 B"
size_names = ["B", "KB", "MB", "GB"]
i = 0
while size_bytes >= 1024 and i < len(size_names) - 1:
size_bytes /= 1024.0
i += 1
return f"{size_bytes:.2f} {size_names[i]}"
if __name__ == "__main__":
# 如果提供命令行参数,使用指定路径
if len(sys.argv) > 1:
target_path = sys.argv[1]
else:
target_path = "."
clean_python_cache(target_path)
增强版本 - 带更多功能和配置
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
高级Python缓存清理工具
"""
import os
import shutil
import sys
import argparse
import json
from pathlib import Path
from datetime import datetime
class CacheCleaner:
"""缓存清理器"""
def __init__(self, config_file=None):
self.stats = {
'directories_deleted': 0,
'files_deleted': 0,
'space_freed': 0,
'errors': 0
}
# 默认清理模式
self.dir_patterns = [
"__pycache__",
"*.egg-info",
"*.egg",
".mypy_cache",
".pytest_cache",
".hypothesis",
".tox",
"build",
"dist",
"*.pyc" # 当作为目录处理
]
self.file_patterns = [
"*.pyc",
"*.pyo",
"*.pyd",
"*.pyc.bak",
"*.so", # Cython编译文件
"*.pdb" # 调试文件
]
# 加载配置文件
if config_file and os.path.exists(config_file):
self.load_config(config_file)
# 排除目录
self.exclude_dirs = ['.git', '.svn', 'venv', 'env', '.env',
'node_modules', '.idea', '.vscode']
def load_config(self, config_file):
"""从JSON文件加载配置"""
try:
with open(config_file, 'r') as f:
config = json.load(f)
if 'dir_patterns' in config:
self.dir_patterns = config['dir_patterns']
if 'file_patterns' in config:
self.file_patterns = config['file_patterns']
if 'exclude_dirs' in config:
self.exclude_dirs = config['exclude_dirs']
except Exception as e:
print(f"加载配置文件失败: {e}")
def clean(self, path=".", verbose=True, dry_run=False):
"""执行清理"""
start_path = Path(path).resolve()
if verbose:
print(f"开始清理: {start_path}")
print(f"时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("-" * 60)
for root, dirs, files in os.walk(start_path):
# 跳过排除目录
dirs[:] = [d for d in dirs if d not in self.exclude_dirs
and not d.startswith('.')]
# 清理目录
for dir_name in dirs[:]: # 使用切片复制,避免修改遍历列表
dir_path = os.path.join(root, dir_name)
for pattern in self.dir_patterns:
if self.match_pattern(dir_name, pattern):
if dry_run:
if verbose:
print(f"[模拟] 将删除目录: {dir_path}")
else:
self.delete_directory(dir_path, verbose)
break
# 清理文件
for file_name in files:
file_path = os.path.join(root, file_name)
for pattern in self.file_patterns:
if self.match_pattern(file_name, pattern):
if dry_run:
if verbose:
print(f"[模拟] 将删除文件: {file_path}")
else:
self.delete_file(file_path, verbose)
break
if verbose:
self.print_summary()
def match_pattern(self, name, pattern):
"""检查名称是否匹配模式"""
if pattern == name:
return True
if pattern.startswith("*") and name.endswith(pattern[1:]):
return True
return False
def delete_directory(self, dir_path, verbose=True):
"""删除目录"""
try:
size = self.get_folder_size(dir_path)
shutil.rmtree(dir_path)
self.stats['directories_deleted'] += 1
self.stats['space_freed'] += size
if verbose:
print(f"删除目录: {dir_path} ({self.format_size(size)})")
except Exception as e:
self.stats['errors'] += 1
if verbose:
print(f"删除目录失败 {dir_path}: {e}")
def delete_file(self, file_path, verbose=True):
"""删除文件"""
try:
size = os.path.getsize(file_path)
os.remove(file_path)
self.stats['files_deleted'] += 1
self.stats['space_freed'] += size
if verbose:
print(f"删除文件: {file_path} ({self.format_size(size)})")
except Exception as e:
self.stats['errors'] += 1
if verbose:
print(f"删除文件失败 {file_path}: {e}")
def get_folder_size(self, folder_path):
"""获取文件夹大小"""
total_size = 0
for dirpath, dirnames, filenames in os.walk(folder_path):
for f in filenames:
fp = os.path.join(dirpath, f)
try:
total_size += os.path.getsize(fp)
except:
pass
return total_size
def format_size(self, size_bytes):
"""格式化文件大小"""
if size_bytes == 0:
return "0 B"
size_names = ["B", "KB", "MB", "GB"]
i = 0
while size_bytes >= 1024 and i < len(size_names) - 1:
size_bytes /= 1024.0
i += 1
return f"{size_bytes:.2f} {size_names[i]}"
def print_summary(self):
"""打印清理摘要"""
print("-" * 60)
print("清理完成!")
print(f"删除目录数: {self.stats['directories_deleted']}")
print(f"删除文件数: {self.stats['files_deleted']}")
print(f"总释放空间: {self.format_size(self.stats['space_freed'])}")
if self.stats['errors'] > 0:
print(f"错误数: {self.stats['errors']}")
print("-" * 60)
def main():
parser = argparse.ArgumentParser(
description='自动清理Python缓存文件',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
示例:
%(prog)s # 清理当前目录
%(prog)s /path/to/project # 清理指定项目
%(prog)s --dry-run # 模拟运行,不实际删除
%(prog)s --config my_config.json # 使用配置文件
%(prog)s --quiet # 静默模式
"""
)
parser.add_argument('path', nargs='?', default='.',
help='要清理的路径 (默认: 当前目录)')
parser.add_argument('--dry-run', '-n', action='store_true',
help='模拟运行,不实际删除')
parser.add_argument('--quiet', '-q', action='store_true',
help='静默模式,只显示摘要')
parser.add_argument('--config', '-c',
help='配置文件路径 (JSON格式)')
parser.add_argument('--version', '-v', action='version',
version='Python Cache Cleaner 1.0')
args = parser.parse_args()
cleaner = CacheCleaner(args.config)
cleaner.clean(args.path, verbose=not args.quiet, dry_run=args.dry_run)
if __name__ == "__main__":
main()
配置文件示例 (config.json)
{
"dir_patterns": [
"__pycache__",
"*.egg-info",
"*.egg",
".mypy_cache",
".pytest_cache",
".hypothesis",
".tox",
"build",
"dist"
],
"file_patterns": [
"*.pyc",
"*.pyo",
"*.pyd",
"*.pyc.bak",
"*.so",
"*.pdb"
],
"exclude_dirs": [
".git",
".svn",
"venv",
"env",
".env",
"node_modules",
".idea",
".vscode"
]
}
使用方法
-
保存脚本为
clean_python_cache.py -
基本使用:
# 清理当前目录 python clean_python_cache.py # 清理指定目录 python clean_python_cache.py /path/to/your/project
-
高级功能:
# 模拟运行(查看会被删除的文件) python clean_python_cache.py --dry-run # 静默模式 python clean_python_cache.py --quiet # 使用配置文件 python clean_python_cache.py --config config.json
这个脚本可以帮助你:
- 清理
__pycache__目录 - 删除
.pyc、.pyo、.pyd等编译文件 - 清理测试缓存(
pytest、mypy等) - 清理构建目录
- 支持模拟运行,避免误删
- 可配置文件模式
使用时请谨慎,建议先使用 --dry-run 选项查看将要删除的文件。