文件夹太乱?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配置文件就行。重载配置
,即可在不重启程序的情况下生效。也可以直接通过程序本身提供的编辑框修改配置,点击保存修改即可。小工具功能开发流程
'图片': ['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']
}
'传入文件名,读取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
file_changes = mkdirAndGetChange(path)
print(file_changes)
WindowsPath('D:/360安全浏览器下载/电子书/9种常用的数据分析方法.pdf')),
...
(WindowsPath('D:/360安全浏览器下载/金融时间序列分析讲义.pdf'),
WindowsPath('D:/360安全浏览器下载/电子书/金融时间序列分析讲义.pdf'))]
src_path.rename(dest_path)
dest_path.rename(src_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开发流程
小小明的代码
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'])
程序打包
h.ico
是程序的图标文件。打包完成后,我们就可以愉快的使用我们的小工具啦。① 关于图标资源打包的问题
C:\Users\用户名\AppData\Local\Temp\
随机目录名,sys._MEIPASS
则存储这个目录的位置。我们可以根据sys模块是否存在_MEIPASS属性来判断是直接运行,还是解压到临时目录再运行。最终定义了如下方法: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;
img = PythonMagick.Image('D:\h.jpg')
img.sample('128x128')
img.write('h.ico')