Python删除超保留期限文件文件夹时TypeError报错排查
自动清理脚本开发问题
需求说明
需要实现两类自动清理规则:
- 超过90天保留期的文件自动删除
- 超过15天保留期的文件夹自动删除
待处理路径存储在config.txt文件中,配置内容如下:
[My Config] path1 = C:\Users\mywork\pa\config\*.xml path2 = C:\Users\mywork\data\unittest\*.csv path3 = C:\Users\mywork\data\inttest\*.csv path4 = C:\Users\mywork\logs
初始实现思路
- 将保留天数转换为秒级时间戳阈值
- 通过
os.stat(path)的st_ctime属性获取文件/文件夹的创建时间 - 将创建时间和时间阈值对比,存储时长超过保留天数时,判断目标类型:
- 是文件则调用
os.remove(path)删除 - 是文件夹则调用
shutil.rmtree()删除
初始编写的代码如下:
- 是文件则调用
import os import shutil import time import glob import configparser def main(): # 初始化删除计数 deleted_folders_count = 0 deleted_files_count = 0 configParser = configparser.RawConfigParser() config = configparser.ConfigParser() config.read_file(open(r'C:\Users\PycharmProjects\untitled\config.txt')) # 读取配置路径 path = [config.get('My Config', 'path1'), config.get('My Config', 'path2'), config.get('My Config', 'path3')] print(path) folder_retn_days = 15 log_retn_days = 90 # 天数转秒级时间戳 folder_seconds = time.time() - (folder_retn_days * 24 * 60 * 60) log_seconds = time.time() - (log_retn_days * 24 * 60 * 60) for idx, word in enumerate(path): print(word) files = glob.glob(word) def remove_file(files): # 删除文件 if not os.remove(files): print(f"{files} is removed successfully") else: print(f"Unable to delete the {files}" def remove_folder(files): # 删除文件夹 if not shutil.rmtree(files): print(f"{files} is removed successfully") else: print(f"Unable to delete the {files}") def get_file_or_folder_age(files): # 获取文件/文件夹ctime ctime = os.stat(files).st_ctime return ctime if folder_seconds >= get_file_or_folder_age(files): print(files) #remove_files(files) #deleted_folders_count += 1
遇到的报错
运行代码时抛出如下类型错误:
ctime = os.stat(files).st_ctime TypeError: stat: path should be string, bytes, os.PathLike or integer, not list
问题排查与修复方案
核心报错原因
glob.glob(word)的返回值是匹配到的所有路径组成的列表,哪怕只匹配到一个路径,返回的也是单元素列表。代码没有遍历列表中的单个路径,直接把整个列表作为参数传给了要求传入单个路径的os.stat(),因此触发类型错误。
代码中其他待修复问题
除了上述核心错误,现有代码还有几处逻辑和语法问题:
- 函数定义位置错误:三个工具函数被定义在for循环内部,每次循环都会重复创建函数,执行效率低且容易引发作用域问题,应该移到循环外部定义。
- 删除结果判断逻辑错误:
os.remove()和shutil.rmtree()执行成功时返回None,删除失败会直接抛出异常,不存在返回False的情况,原有if not 方法调用的判断逻辑永远走不到失败分支,也无法正确捕获删除错误。需要用try/except块捕获删除操作的异常来判断执行结果。 - 配置项遗漏:配置中的
path4是需要按15天规则清理的日志文件夹路径,原有代码只读取了path1-path3,漏掉了该路径。 - 保留规则匹配错误:原有判断逻辑统一使用15天的文件夹保留阈值,没有区分90天文件保留期、15天文件夹保留期两类规则。
- 语法错误:
remove_file函数中打印删除失败的行缺少右括号,remove_folder函数缩进错误,被嵌套在了remove_file函数内部,无法正常调用。
修复后可运行代码
import os import shutil import time import glob import configparser def get_file_or_folder_age(path): # 获取文件/文件夹的创建时间戳 return os.stat(path).st_ctime def remove_file(path): try: os.remove(path) print(f"{path} 删除成功") return True except Exception as e: print(f"删除 {path} 失败,错误信息:{str(e)}") return False def remove_folder(path): try: shutil.rmtree(path) print(f"{path} 文件夹删除成功") return True except Exception as e: print(f"删除文件夹 {path} 失败,错误信息:{str(e)}") return False def main(): deleted_folders_count = 0 deleted_files_count = 0 config = configparser.ConfigParser() config.read(r'C:\Users\PycharmProjects\untitled\config.txt', encoding='utf-8') # 分两类配置路径:文件路径走90天保留规则,文件夹路径走15天保留规则 file_patterns = [ config.get('My Config', 'path1'), config.get('My Config', 'path2'), config.get('My Config', 'path3') ] folder_paths = [ config.get('My Config', 'path4') ] folder_retn_days = 15 file_retn_days = 90 # 计算时间阈值 current_time = time.time() folder_threshold = current_time - (folder_retn_days * 24 * 60 * 60) file_threshold = current_time - (file_retn_days * 24 * 60 * 60) # 处理过期文件 for pattern in file_patterns: # 遍历glob返回的路径列表,逐个处理单个文件 for file_path in glob.glob(pattern): if os.path.isfile(file_path): file_ctime = get_file_or_folder_age(file_path) if file_ctime < file_threshold: if remove_file(file_path): deleted_files_count += 1 # 处理过期文件夹 for folder_path in folder_paths: if os.path.isdir(folder_path): folder_ctime = get_file_or_folder_age(folder_path) if folder_ctime < folder_threshold: if remove_folder(folder_path): deleted_folders_count += 1 print(f"清理完成,共删除{deleted_files_count}个文件,{deleted_folders_count}个文件夹") if __name__ == "__main__": main()
注意:Windows系统下
st_ctime是文件/文件夹的创建时间,如果需求是按最后修改时间判断,需要替换为st_mtime属性。
内容的提问来源于stack exchange,提问作者Priya
相关产品推荐
相关产品推荐

