文件夹太乱?Python小程序瞬间帮你整理到位
糟透了
一键整理桌面
的软件很多,但是对于其他路径下的文件,我同样需要整理,于是我想到使用Python,完成这个需求。
效果展示
图片
、视频
、音频
、文档
、压缩文件
、常用格式
、程序脚本
、可执行程序
和字体文件
。# 不同文件组成的嵌套字典
file_dict = {
'图片': ['jpg','png','gif','webp'],
'视频': ['rmvb','mp4','avi','mkv','flv'],
"音频": ['cd','wave','aiff','mpeg','mp3','mpeg-4'],
'文档': ['xls','xlsx','csv','doc','docx','ppt','pptx','pdf','txt'],
'压缩文件': ['7z','ace','bz','jar','rar','tar','zip','gz'],
'常用格式': ['json','xml','md','ximd'],
'程序脚本': ['py','java','html','sql','r','css','cpp','c','sas','js','go'],
'可执行程序': ['exe','bat','lnk','sys','com'],
'字体文件': ['eot','otf','fon','font','ttf','ttc','woff','woff2']
}
常用格式
需要为大家解释一下,对于平时经常使用,但是又不知道放在哪一类的文件,都存放在这里。开发思路
os模块
、shutil模块
、glob模块
,它们搭配使用,用来处理文件和文件夹,简直超给力!① 任意给定一个文件路径; ② 获取当前文件路径下的所有文件,并取得每个文件对应的后缀; ③ 判断每个文件,是否在指定的嵌套字典中,并返回对应的文件分类; ④ 判断每个文件分类的文件夹是否存在。因为需要创建新的文件夹,用于分类存放文件; ⑤ 将每个文件,复制到对应的分类中;
# 导入相关库
import os
import glob
import shutil
# 采用input()函数,动态输入要处理的文件路径。
path = input("请输入要清理的文件路径:")
# 定义一个文件字典,不同的文件类型,属于不同的文件夹,一共9个大类。
file_dict = {
'图片': ['jpg','png','gif','webp'],
'视频': ['rmvb','mp4','avi','mkv','flv'],
"音频": ['cd','wave','aiff','mpeg','mp3','mpeg-4'],
'文档': ['xls','xlsx','csv','doc','docx','ppt','pptx','pdf','txt'],
'压缩文件': ['7z','ace','bz','jar','rar','tar','zip','gz'],
'常用格式': ['json','xml','md','ximd'],
'程序脚本': ['py','java','html','sql','r','css','cpp','c','sas','js','go'],
'可执行程序': ['exe','bat','lnk','sys','com'],
'字体文件': ['eot','otf','fon','font','ttf','ttc','woff','woff2']
}
# 定义一个函数,传入每个文件对应的后缀。判断文件是否存在于字典file_dict中;
# 如果存在,返回对应的文件夹名;如果不存在,将该文件夹命名为"未知分类";
def func(suffix):
for name, type_list in file_dict.items():
if suffix.lower() in type_list:
return name
return "未知分类"
# 递归获取 "待处理文件路径" 下的所有文件和文件夹。
for file in glob.glob(f"{path}/**/*",recursive=True):
# 由于我们是对文件分类,这里需要挑选出文件来。
if os.path.isfile(file):
# 由于isfile()函数,获取的是每个文件的全路径。这里再调用basename()函数,直接获取文件名;
file_name = os.path.basename(file)
suffix = file_name.split(".")[-1]
# 判断 "文件名" 是否在字典中。
name = func(suffix)
#print(func(suffix))
# 根据每个文件分类,创建各自对应的文件夹。
if not os.path.exists(f"{path}\\{name}"):
os.mkdir(f"{path}\\{name}")
# 将文件复制到各自对应的文件夹中。
shutil.copy(file,f"{path}\\{name}")

窗口界面
可视化界面
,也没有将程序打包
,所以我自己用没问题,要是发给别人就不太好使了。小工具效果展示


开始整理
,选择待整理的文件夹后,就可以进行整理了,下面是整理前后的效果图。
回退
功能和删除空文件夹
功能。回退功能就是当你将文件夹整理完毕后,点击回退,又可以恢复到文件夹原始模样。私人定制
,只需要去修改同一目录下的config.json配置文件就行。
重载配置
,即可在不重启程序的情况下生效。也可以直接通过程序本身提供的编辑框修改配置,点击保存修改即可。小工具功能开发流程
file_dict = {
'图片': ["jpeg", 'jpg', 'png', 'gif', 'webp', "bmp", "bpg", "svg", "heif", "psd"],
'视频': ['rmvb', 'mp4', 'avi', 'mkv', 'flv', "wmv", "mov", "mpg", "mpeg", "3gp"],
"音频": ['m4a', 'aac', 'ogg', 'oga', 'mp3', 'wma', "wav"],
"电子书": ['pdf', "epub", "mobi", "azw3", "chm", "txt"],
"数据与表格": ['xls', 'xlsx', "xlsm", 'csv', 'json', 'xml'],
"文档": ['doc', 'docx', 'ppt', 'pptx', 'md', ".txt"],
"思维导图": ["emmx", "mmap", "xmind"],
'程序脚本': ['py', 'java', 'html', 'sql', 'r', 'css', 'cpp', 'c', 'js', 'go'],
'压缩文件': ["tar", "gz", "rz", "7z", "dmg", "rar", "xar", "zip", "iso"],
'可执行程序': ['exe', 'bat', 'sys', 'com'],
'字体文件': ['eot', 'otf', 'fon', 'font', 'ttf', 'ttc', 'woff', 'woff2']
}
def get_file_type(filename):
"传入文件名,读取file_dict配置,根据后缀判断文件类型"
for file_type, suffixs in file_dict.items():
for suffix in suffixs:
if filename.endswith("."+suffix.lstrip(".")):
return file_type
return "未知类型"
get_file_type(r"D:\360安全浏览器下载\document.pdf")
# 结果如下:电子书
from pathlib import Path
def mkdirAndGetChange(path):
path = Path(path)
result = []
for file in path.glob("*"):
if file.is_dir():
continue
src_path = file.absolute()
dest_dir = get_file_type(file.name)
dest_path = path/dest_dir/file.name
dest_dir = dest_path.parent
if not dest_dir.exists():
dest_dir.mkdir()
result.append((src_path, dest_path))
return result
path = r"D:\360安全浏览器下载"
file_changes = mkdirAndGetChange(path)
print(file_changes)
[(WindowsPath('D:/360安全浏览器下载/9种常用的数据分析方法.pdf'),
WindowsPath('D:/360安全浏览器下载/电子书/9种常用的数据分析方法.pdf')),
...
(WindowsPath('D:/360安全浏览器下载/金融时间序列分析讲义.pdf'),
WindowsPath('D:/360安全浏览器下载/电子书/金融时间序列分析讲义.pdf'))]
for src_path, dest_path in file_changes:
src_path.rename(dest_path)
for src_path, dest_path in file_changes:
dest_path.rename(src_path)
def clear_black_dir(path):
path = Path(path)
for file in path.glob("*"):
if not file.is_dir():
continue
if not os.listdir(file):
file.rmdir()
path = r"D:\360安全浏览器下载"
clear_black_dir(path)
小工具GUI开发流程
"""python
小小明的代码
CSDN主页:https://blog.csdn.net/as604049322
"""
__author__ = '小小明'
__time__ = '2021/8/11'
import json
import os
from pathlib import Path
def load_config_json():
with open("config.json", encoding="u8") as f:
config_json = f.read()
return config_json
def save_config(config):
with open("config.json", "w", encoding="u8") as f:
f.write(config)
config_json = load_config_json()
file_dict = json.loads(config_json)
def get_file_type(filename):
"传入文件名,读取file_dict配置,根据后缀判断文件类型"
for file_type, suffixs in file_dict.items():
for suffix in suffixs:
if filename.endswith("." + suffix.lstrip(".")):
return file_type
return "未知类型"
def mkdirAndGetChange(path):
path = Path(path)
result = []
for file in path.glob("*"):
if file.is_dir():
continue
src_path = file.absolute()
dest_dir = get_file_type(file.name)
dest_path = path / dest_dir / file.name
dest_dir = dest_path.parent
if not dest_dir.exists():
dest_dir.mkdir()
result.append((src_path, dest_path))
return result
def clear_black_dir(path):
path = Path(path)
num = 0
for file in path.glob("*"):
if not file.is_dir():
continue
if not os.listdir(file):
file.rmdir()
num += 1
return num
{
"图片": ["jpeg", "jpg", "png", "gif", "webp", "bmp", "bpg", "svg", "heif", "psd"],
"视频": ["rmvb", "mp4", "avi", "mkv", "flv", "wmv", "mov", "mpg", "mpeg", "3gp"],
"音频": ["m4a", "aac", "ogg", "oga", "mp3", "wma", "wav"],
"电子书": ["pdf", "epub", "mobi", "azw3", "chm", "txt"],
"数据与表格": ["xls", "xlsx", "xlsm", "csv", "json", "xml"],
"文档": ["doc", "docx", "ppt", "pptx", "md", ".txt"],
"思维导图": ["emmx", "mmap", "xmind"],
"程序脚本": ["py", "java", "html", "sql", "r", "css", "cpp", "c", "js", "go"],
"压缩文件": ["tar", "gz", "rz", "7z", "dmg", "rar", "xar", "zip", "iso"],
"可执行程序": ["exe", "bat", "sys", "com"],
"字体文件": ["eot", "otf", "fon", "font", "ttf", "ttc", "woff", "woff2"]
}
"""
小小明的代码
CSDN主页:https://blog.csdn.net/as604049322
"""
__author__ = '小小明'
__time__ = '2021/8/11'
import json
import os
import sys
import PySimpleGUI as sg
import auto_organize
sg.change_look_and_feel("LightBlue")
layout = [
[sg.Text("被处理的文件夹路径(默认为当前路径):")],
[sg.In(key="path"),
sg.FolderBrowse('...', target='path')],
[
sg.Button('开始整理', enable_events=True, key="auto_organize", font=('楷体', 15)),
sg.Button('回退', enable_events=True, key="back_before", pad=(20, 0), font=('楷体', 15)),
sg.Button('删除空文件夹', enable_events=True, key="del_black", pad=(10, 0), font=('楷体', 15))
],
[sg.Text("改名配置:"),
sg.Button('重载配置', enable_events=True, key="reload_config"),
sg.Button('保存修改', enable_events=True, key="save_config")
],
[sg.Multiline(size=(46, 12), key="out")],
[sg.Text("@小小明:https://blog.csdn.net/as604049322"), ],
]
def resource_path(relative_path):
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, relative_path)
window = sg.Window('文件夹整理工具 by 小小明', layout, icon=resource_path("h.ico"))
window.finalize()
window["out"].update(auto_organize.config_json)
file_changes = None
while True:
event, values = window.read()
# print(event, values)
if event in (None,):
break # 相当于关闭界面
elif event == "auto_organize":
path = values['path']
if os.path.abspath(path) == os.path.abspath("."):
sg.popup("未选择路径或输入的路径为当前目录,\n不允许选择程序所在的路径!", title="提示")
continue
file_changes = auto_organize.mkdirAndGetChange(path)
for src_path, dest_path in file_changes:
src_path.rename(dest_path)
sg.popup("整理完成,允许一次回退重置!", title="提示")
elif event == "back_before":
if not file_changes:
sg.popup("未执行过整理操作!", title="提示")
continue
for src_path, dest_path in file_changes:
dest_path.rename(src_path)
auto_organize.clear_black_dir(values['path'])
file_changes = None
sg.popup("回退完成并删除了全部的空文件夹!", title="提示")
elif event == "del_black":
n = auto_organize.clear_black_dir(values['path'])
sg.popup(f"共删除了{n}个空文件夹!", title="提示")
elif event == "reload_config":
auto_organize.config_json = auto_organize.load_config_json()
auto_organize.file_dict = json.loads(auto_organize.config_json)
window["out"].update(auto_organize.config_json)
elif event == "save_config":
auto_organize.save_config(values["out"])
程序打包
pyinstaller -Fw --icon=h.ico auto_organize_gui.py --add-data="h.ico;/"
h.ico
是程序的图标文件。打包完成后,我们就可以愉快的使用我们的小工具啦。① 关于图标资源打包的问题
sg.Window('PySimpleGUI',layout,icon='ico.ico')
C:\Users\用户名\AppData\Local\Temp\
随机目录名,sys._MEIPASS
则存储这个目录的位置。我们可以根据sys模块是否存在_MEIPASS属性来判断是直接运行,还是解压到临时目录再运行。最终定义了如下方法:def resource_path(relative_path):
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, relative_path)
–add-data
参数,添加用 ; 分隔的两个路径。--add-data="h.ico;/"
表示将h.ico
文件打包进去,运行时解压到根目录下。② 如何制作ico图标
使用ico生成的在线网站; 使用本地软件imagine另存图片为ico; 使用python库PythonMagick;
pip install PythonMagick-0.9.19-cp37-cp37m-win_amd64.whl
import PythonMagick
img = PythonMagick.Image("D:\h.jpg")
img.sample('128x128')
img.write('h.ico')
作者:黄伟呢、小小明
_往期文章推荐_
评论