如何用Python压缩指定子文件夹中的.yml文件并去除嵌套结构
问题描述
我有一个文件夹“a”,其下包含子文件夹“b”,“b”中又有子文件夹“c”,“c”内存储着.yml文件。我需要压缩子文件夹“b”或“c”中的所有.yml文件,且生成的压缩包不保留嵌套目录结构,仅包含所有.yml文件。但目前编写的Python代码未能压缩所有子文件夹中的.yml文件,原代码如下:
import os from zipfile import ZipFile # # Adding files that need to be zipped directory_to_zip = r'filepath' # Create a ZipFile Object with ZipFile(r'filepath\helper.zip', 'w') as zip_object: # Traverse the directory and add YAML files to the zip for root, dirs, files in os.walk(directory_to_zip): for file in files: if file.endswith('.yml'): # Create the complete filepath file_path = os.path.join(root, file) # Write the file to the zip file with just the filename, ignoring directories zip_object.write(file_path, file) # Check to see if the zip file is created if os.path.exists(r'filepath\helper.zip'): print("ZIP file created") else: print("ZIP file not created")
问题排查与修正
原代码的遍历逻辑本身是正确的,无法压缩到文件的核心原因几乎都是目标路径设置错误:
- 若要压缩
b文件夹下所有子目录(包括c)里的.yml文件,directory_to_zip需设为实际的b文件夹路径(比如r'a\b',根据你的本地路径调整) - 若仅需压缩
c文件夹内的.yml文件,直接将directory_to_zip设为r'a\b\c'即可
另外需要注意:如果不同子目录下存在同名的.yml文件,直接用文件名作为压缩包内的路径会导致后续文件覆盖之前的。针对这种场景,可通过给文件名添加相对目录前缀来避免冲突,以下是两种场景的修正代码:
基础修正版(无同名.yml文件场景)
import os from zipfile import ZipFile # 替换为你的目标文件夹实际路径,如r'a\b'或r'a\b\c' directory_to_zip = r'a\b' zip_output_path = r'helper.zip' with ZipFile(zip_output_path, 'w') as zip_object: # 遍历目标目录下所有文件 for root, _, files in os.walk(directory_to_zip): for file in files: if file.endswith('.yml'): file_path = os.path.join(root, file) # 仅保留文件名,丢弃原目录结构 zip_object.write(file_path, arcname=file) # 输出结果检查 print("ZIP file created" if os.path.exists(zip_output_path) else "ZIP file not created")
防覆盖版(存在同名.yml文件场景)
import os from zipfile import ZipFile directory_to_zip = r'a\b' zip_output_path = r'helper.zip' with ZipFile(zip_output_path, 'w') as zip_object: for root, _, files in os.walk(directory_to_zip): # 获取当前目录相对于目标根目录的相对路径 rel_dir = os.path.relpath(root, directory_to_zip) for file in files: if file.endswith('.yml'): file_path = os.path.join(root, file) # 用相对路径+文件名生成唯一标识,避免同名覆盖 # 示例:c目录下的file.yml会被命名为c/file.yml,也可替换成下划线格式c_file.yml arcname = os.path.join(rel_dir, file) if rel_dir != '.' else file # 若要替换路径分隔符为下划线,取消下面一行注释并替换上面的arcname # arcname = f"{rel_dir.replace(os.sep, '_')}_{file}" if rel_dir != '.' else file zip_object.write(file_path, arcname=arcname) print("ZIP file created" if os.path.exists(zip_output_path) else "ZIP file not created")
内容的提问来源于stack exchange,提问作者testenthu
相关产品推荐
相关产品推荐

