20个实用Python脚本:从文件整理到自动化办公的效率提升指南
发布时间:2026/9/27 4:09:49来源:尧图网络
20个超实用Python脚本真的是我从日常办公里一点点攒出来的。你没看错不是那种教学用的Hello World而是直接能改善工作流、省下大量重复劳动的东西。不管你是刚入门的Python新手还是已经在用脚本处理数据的职场老手这套脚本列表都值得花几分钟看看。把整理文件、批量改格式、清理重复数据、监控文件夹变动这类活从手动点点点变成双击或者敲一行命令就能完成这就是标题里有如神助的真正含义。我下面会把这20个脚本分类拆开讲还会挑几个代表性的给出完整代码和踩坑记录方便你直接抄走改改就能用。1. 这批脚本是怎么攒出来的需求盘点与分类思路1.1 为什么是20个不是10个也不是30个说实话20这个数字不是一开始就定好的。我最初只是把平时在命令行里反复敲的Python片段收集起来发现数量很快就超过了20个。于是我做了一次减法凡是一年用不到两次的删掉凡是需要大量人工干预才能跑通的再改改直到真正能一键执行凡是和已有脚本功能高度重叠的合并掉。最终留下的这20个都是高频场景、低维护成本的小工具。选20个还有一个实际原因数量太少覆盖不了日常遇到的重复劳动数量太多又会让维护成本变高脚本这东西一旦不维护三个月后再看就跟天书一样。我当时的思路是每个脚本尽量只做一件事把功能收敛到输入什么、输出什么都极度清晰的程度。这样即使在半年后重新翻出来用也不需要回忆太多背景。1.2 脚本分成了哪几类每类解决什么问题我把这20个脚本分成了5个大类这样梳理起来更有条理也方便你在需要的时候按图索骥文件管理类4个批量重命名、重复文件查找、大文件扫描、按类型归档。数据表格类4个CSV合并与拆分、Excel工作表拆分、JSON与表格互转、日志解析汇总。文本与剪贴板类4个剪贴板历史记录、词频统计、批量文本替换、随机密码生成。批量处理类4个图片批量压缩、图片格式转换、PDF合并拆分、批量发送邮件。系统与监控类4个目录变动监控、定时清理旧文件、端口连通性检测、文本排版清理。这个分类逻辑其实很直接你日常用电脑遇到的重复活无非就是文件、数据、文本这三个对象。文件乱了要整理数据碎了要合并文本脏了要清洗再加上重复发送、重复转换、重复检查这一类批量动作基本就覆盖了80%的办公场景。1.3 一类脚本背后共同的代码弹药库虽然脚本功能各不相同但它们共用的底层工具高度一致。我在动手写之前先把自己最常用的几个标准库过了一遍pathlib处理路径的现代方式比os.path好用太多尤其适合做文件遍历和重命名。shutil复制、移动、压缩文件归档脚本离不开它。hashlib计算文件哈希MD5重复文件查找的底层依据。re正则表达式日志解析和文本清洗都靠它。json与csv数据格式转换的基础。sys与argparse读取命令行参数让脚本可以复用而不是写死。我的建议是你要想把这20个脚本玩得转不需要系统性学习Python的全部知识只要掌握上面这些标准库的常用API再配合一点列表推导式和with语句就能覆盖绝大部分场景。另外有几个第三方库也会用到比如pandas处理大型CSV、PIL处理图片、pypdf处理PDF、watchdog监控文件系统这些我在下一章会专门说明选型原因。2. 动手前的关键准备环境、依赖和脚本骨架2.1 Python版本与依赖库怎么选先说版本这直接影响你后面会不会踩坑。我自己主力环境用的是Python 3.9到3.12不等不同机器上版本会有差异。如果你是新装环境直接装3.10以上的稳定版就好这几个和脚本相关的标准库在3.8以上行为基本一致但3.8以下有些语法比如海象运算符不支持旧环境跑新代码容易报错。第三方库的选择上我的原则是能用标准库就用标准库标准库不够再引第三方。像CSV合并如果文件不大纯标准库的csv模块就够了但如果遇到几个GB的大文件我会切换到pandas因为它的分块读取和向量化操作明显快得多。图片压缩、格式转换用PillowPDF相关操作我用pypdf它在处理合并、拆分、加密这些基础需求时API很稳定目录监控用watchdog因为它的事件驱动模式比while True轮询要可靠得多。另外强烈建议使用虚拟环境哪怕你只是在本机写个工具脚本。我用python -m venv建一个专门的scripts_env把需要用到的第三方库都装进去这样不会污染系统的全局Python环境换电脑迁移时也可以pip freeze requirements.txt一键复现。2.2 一个适合所有脚本的通用模板脚本写多了以后我逐渐形成了一个固定的骨架。不管脚本功能是什么开头都长这样#!/usr/bin/env python3 # -*- coding: utf-8 -*- 功能说明一句话说清楚这个脚本是干什么的 用法示例python script.py input_path [options] import argparse import sys from pathlib import Path def parse_args(): parser argparse.ArgumentParser(description脚本功能说明) parser.add_argument(input_path, nargs?, default., help输入路径) parser.add_argument(--output, -o, defaultoutput, help输出目录) return parser.parse_args() def main(): args parse_args() # 核心逻辑写在这里 pass if __name__ __main__: main()为什么坚持用这个骨架因为我踩过太多没有接口、参数写死的脚本的坑。比如你写了个批量重命名脚本直接把目录路径写在代码里今天在这个目录跑没问题明天换一个目录就得改代码改完还可能引入笔误。用argparse之后每次只需要在命令行指定目录就行脚本变成了一个真正可复用的工具而不是一段一次性代码。2.3 命令行参数处理的三种姿势简单脚本可以只用sys.argv比如sys.argv[1]就是第一个参数但一旦参数多了就容易乱。我推荐的进阶姿势是argparse不仅自动生成帮助文档还能做类型校验。比如定义一个--days参数并指定typeint用户不小心传了字母时程序会直接提示错误而不是运行到一半才崩溃。第三个姿势是用os.environ读取环境变量这主要用在定时任务里。比如备份脚本的保留天数、备份目录等通过环境变量传入这样把脚本部署到不同机器时就不用改代码逻辑了。这三种姿势没有绝对的优劣关键是根据脚本的使用频率来决定自己随手用的小工具用sys.argv最快要分享给别人用的一定要上argparse跑在服务器定时任务里的考虑环境变量。3. 20个脚本逐个看核心功能与关键逻辑3.1 文件管理类脚本1-4重命名、去重、归档、扫描第1个脚本是批量重命名。最典型的场景是相机照片导出来全是IMG_20240101_142503.jpg这种文件名你希望按日期加序号重命名成2024-01-01_001.jpg。核心逻辑就是用pathlib遍历目录里的文件从每个文件的元信息里取出日期用f-string重新组合名字再用os.rename改掉。这里有个容易忽略的点重命名前要先检查目标文件名是否已经存在否则会覆盖旧文件后来我改用Path.rename之前加上if not target.exists()判断。第2个脚本是重复文件查找。原理不复杂遍历目录对每个文件计算MD5值把哈希值相同的文件放在一起。这里有个效率优化技巧先按文件大小分组只有大小完全一致的文件才去算哈希因为MD5计算在大文件上很耗时先按大小筛掉大部分候选文件可以把耗时减少一个数量级。第3个脚本是大文件扫描。它的用处是当电脑磁盘空间不够时快速找出哪些目录里躺着吃空间的大户。我用的是os.walk遍历加getsize累加再把结果按大小排序输出Top 20。实际上tkinter还可以给它做个简单的图形界面但我一般不建议给这种排查类脚本加UI命令行输出反而更快。第4个脚本是按类型归档。下载目录里总是堆着各种PDF、图片、压缩包、安装程序这个脚本做的事就是按扩展名把它们分门别类移动到对应子目录。比如Downloads/build/、Downloads/images/、Downloads/archives/。关键逻辑是维护一个扩展名到目录名的映射表遇到不认识的扩展名统一放到misc/。我每周都会运行一次几个月下来下载目录从像垃圾场变成了随时能找到东西。3.2 数据表格类脚本5-8CSV、Excel、JSON、日志第5个脚本是CSV合并与拆分。把同一个目录下几十个结构相同的CSV文件合并成一个或者把一个大CSV按行数拆成多个小文件。用pandas的话合并就是pd.concat一行代码的事拆分则要配合chunksize按块读取避免一次性加载到内存导致机器卡死。我做数据对账时经常要用它尤其是从不同系统导出的明细表格式一样但数据量超大。第6个脚本是Excel工作表拆分。比如一个总表里有几十个销售团队的数据你想按团队名这一列把所有行拆分成独立的Excel文件。用pandas处理很简单groupby按关键列分组后to_excel逐组写出去。这里要注意两点第一openpyxl作为Excel写入引擎必须装好第二写入时不要循环里反复打开工作簿应该先收集好所有数据再批量写入速度提升明显。第7个脚本是JSON与表格互转。在对接接口时经常要处理嵌套非常深的JSON我习惯先把JSON转成拍平的表格便于查看再把修改后的表格转回JSON去调接口。pandas的json_normalize可以解开嵌套结构反过来用to_json(orientrecords)就能转回数组格式。对于特别深的嵌套结构我会先把每一层路径拼成字段名再保存这个脚本处理起来非常顺手。第8个脚本是日志解析汇总。系统运行日志动辄几十万行光靠CtrlF找错误很浪费时间。我写了一个脚本用正则表达式匹配常见的错误关键字ERROR、Exception、Traceback等然后collections.Counter统计每个错误类型出现的次数和时间分布最后输出一个汇总报告。这个脚本救过我好几次线上问题排查时几秒钟就能定位到大致的故障模块。3.3 文本与剪贴板类脚本9-12常用但要细心第9个脚本是剪贴板历史记录。系统自带剪贴板只能保存最后一次复制的内容但我写代码或者写报告时经常需要连续复制好几段内容。我用pyperclip库循环读取剪贴板内容每次检测到变化就往一个本地文本文件里追加一条记录并带上时间戳。要注意的是这个脚本需要一直后台运行我一般搭配开机自启来用Windows下可以用任务计划程序macOS下可以用launchd。第10个脚本是词频统计。做文本分析、写总结报告时我想快速知道一段文字里哪些词出现得最频繁。先分词然后Counter.most_common取前20个词配合jieba库就能处理中文文本。这里有个心得统计之前要做好小写化、去除标点和停用词的处理否则看到的结果会被的、了、在这类虚词刷屏。第11个脚本是批量文本替换。比如一个项目里几十个文件都把旧术语customer写成了client需要全部替换过来。用pathlib递归找到所有目标文件逐个以UTF-8编码读取执行replace后再写回。这个脚本看起来简单但危险性也高如果替换词写错可能导致一批文件改错。所以在写回之前我总会先把匹配数量统计出来人工看一眼再决定是否真正执行写回千万别一步到位。第12个脚本是随机密码生成。它可以生成包含大小写字母、数字、特殊字符的指定长度密码并支持一次生成多条。我用它来生成服务器密码和数据库密码生成的密码默认还会排除掉容易混淆的字符比如0和O、1和l这样打印出来被人拿在手上抄也不容易看错。3.4 批量处理类脚本13-16图片、PDF、邮件第13个脚本是图片批量压缩。运营同事经常需要把一批商品图压缩到300KB以内再上传我直接用Pillow打开图片指定质量参数后重新保存到输出目录。这里的关键参数是quality一般70左右肉眼几乎看不出画质损失但文件大小能缩小一半以上。如果原图尺寸很大还可以配合thumbnail先等比缩放进一步压缩体积。第14个脚本是图片批量格式转换。从PNG转JPG、JPG转WebP这类转换需求很常见。用Pillow十几行代码就能实现注意PNG转JPG时需要先把带透明通道的图片合成到白色背景上否则输出会在透明区域变成黑色块这是个非常容易翻车的细节。第15个脚本是PDF合并与拆分。合并就是把多个PDF按顺序拼接成一个拆分则是指定页码范围抽取出来生成新文件。我用pypdf来实现核心就是PdfReader读取、PdfWriter写入。这个脚本在处理扫描件、合同材料时几乎成了办公室的公共工具同事经常把好几份PDF丢给我合并。拆分时页码参数建议做成--pages 1-3,5,8-10这种格式用起来很灵活。第16个脚本是批量发送邮件。年终汇报时经常要给分布在不同部门的人发不同的附件如果一个个打开邮箱操作一下午就没了。我用email和smtplib写了一个脚本读取一个Excel或CSV里面每一行包含收件人、主题、正文模板、附件路径脚本用字符串模板的占位符把每封邮件个性化再通过SMTP服务器发出。这里最需要注意的是密码或授权码安全不要在代码里硬编码建议从环境变量或独立的配置文件中读取。3.5 系统与监控类脚本17-20自动化的前端哨兵第17个脚本是目录变动监控。比如我有个待处理文件目录新文件一放进来脚本立刻自动执行处理流程转格式、归档、入Excel。原理是watchdog库的Observer监听文件系统的创建、修改、删除事件在回调函数里写业务逻辑。这个脚本把人盯文件夹变成程序盯文件夹大幅提升了工作的响应速度。第18个脚本是定时清理旧文件。按天为单位把某个目录下超过保留期限的文件移动或删除避免日志、临时文件、导出的报表把磁盘塞满。脚本通过--days参数设置保留天数默认30天。它的核心就是比较文件修改时间和当前时间的差值配合crontab或Windows计划任务使用。我强烈建议清理类脚本不要直接删除而是先移动到trash/目录等运行稳定后再改成真正删除防止误删重要文件。第19个脚本是端口连通性检测。排查网络问题、验证服务是否正常启动时用telnet太原始用专业工具又太重。我写了一个轻量脚本传入主机名和端口列表脚本用socket去逐一探测连接输出每个端口的通断状态和响应耗时。这个脚本我在部署服务时几乎必用几台机器的端口状态一眼就能看完。第20个脚本是文本排版清理。复制来的内容经常带着乱七八糟的全角半角标点、多余空格、换行符。这个脚本能自动统一引号、转全半角、去掉行首行尾空格、合并连续空行。写公众号文章、整理会议纪要时非常实用。实现上就是一组正则替换规则规则写得多之后整个脚本会演化成一个小的文本清洁工。4. 从需求到落地四个代表性脚本的完整实现4.1 脚本一下载目录自动归档这个脚本是我用得最频繁的代码相对简单但非常能说明问题#!/usr/bin/env python3 # -*- coding: utf-8 -*- 按扩展名自动归档下载目录中的文件 import argparse import shutil from pathlib import Path EXT_MAP { .jpg: images, .png: images, .gif: images, .webp: images, .doc: docs, .docx: docs, .pdf: docs, .txt: docs, .zip: archives, .rar: archives, .7z: archives, .tar.gz: archives, .exe: apps, .msi: apps, } def main(): parser argparse.ArgumentParser(description自动归档下载目录) parser.add_argument(source, nargs?, default~/Downloads, help要整理的目录) parser.add_argument(--dry-run, actionstore_true, help只预览不移动文件) args parser.parse_args() source Path(args.source).expanduser() if not source.is_dir(): print(f目录不存在: {source}) return for item in source.iterdir(): if item.is_dir(): # 不移动子目录只处理文件 continue ext .join(item.suffixes) # 保留 .tar.gz 这类复合后缀 target_dir EXT_MAP.get(ext.lower(), misc) target source / target_dir target.mkdir(exist_okTrue) if args.dry_run: print(f[预览] {item.name} - {target_dir}/{item.name}) else: shutil.move(str(item), str(target / item.name)) print(f[移动] {item.name} - {target_dir}/{item.name}) if __name__ __main__: main()这个脚本验证了一个关键细节iterdir()只处理当前目录下的文件不会递归到子目录。这符合整理下载目录的预期因为下载目录里本身不应该有太深的层级。.join(item.suffixes)则处理了xxx.tar.gz这种双后缀文件避免它被归到misc里。--dry-run参数是我后来加上的。加之前我吃过一次亏有个文件已经存在于目标目录shutil.move直接覆盖了同名文件导致我一份旧版本文件被新文件覆盖了。后来每次正式移动前我都会先跑一遍--dry-run核对一遍列表确认无误再真正执行。4.2 脚本二CSV大文件拆分工作里经常遇到财务或数据分析同事丢过来一个几百万行的CSV说帮忙按日期拆一下。我实现了一个按行数拆分的脚本#!/usr/bin/env python3 # -*- coding: utf-8 -*- 把超大CSV按固定行数拆分成多个小文件 import csv import argparse from pathlib import Path def main(): parser argparse.ArgumentParser(descriptionCSV按行数拆分) parser.add_argument(csv_path, helpCSV文件路径) parser.add_argument(--rows, -r, typeint, default100000, help每个文件多少行) parser.add_argument(--output, -o, defaultsplit_output, help输出目录) args parser.parse_args() src Path(args.csv_path) out_dir Path(args.output) out_dir.mkdir(exist_okTrue) with open(src, r, encodingutf-8, newline) as f: reader csv.reader(f) header next(reader) # 保留表头 file_count 1 current_rows [] for row in reader: current_rows.append(row) if len(current_rows) args.rows: write_part(out_dir, header, current_rows, file_count, src.stem) file_count 1 current_rows [] if current_rows: write_part(out_dir, header, current_rows, file_count, src.stem) def write_part(out_dir, header, rows, index, stem): out_path out_dir / f{stem}_part_{index}.csv with open(out_path, w, encodingutf-8, newline) as f: writer csv.writer(f) writer.writerow(header) writer.writerows(rows) print(f已生成: {out_path}{len(rows)} 行) if __name__ __main__: main()这里我没有用pandas因为对大文件来说pandas一次性读入内存会有风险而csv模块按行迭代读取内存占用非常稳定。虽然逐行读写速度不算最快但胜在可靠。要拆分时按行数而不是按某个字段值因为按字段拆分用pandas groupby更自然但如果字段值分布极度不均匀还是按行数拆分更可控。4.3 脚本三日志文件错误汇总当年排查一个线上服务问题时我打开日志文件发现里面有几十万行手动翻看完全不可能。后来写出的这个错误汇总脚本帮我快速定位了问题#!/usr/bin/env python3 # -*- coding: utf-8 -*- 扫描日志文件统计各类错误出现的次数并按时间汇总 import re from collections import Counter, defaultdict from pathlib import Path # 匹配常见错误形式的正则 ERROR_PATTERNS [ rERROR.*, r.*Exception.*, rTraceback \(most recent call last\):, rFailed to .*, rTimeout.*, ] def main(log_path, top_n15): log_file Path(log_path) counter Counter() time_bucket defaultdict(Counter) line_pattern re.compile(r(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\s(\w)\s(.*)) with open(log_file, r, encodingutf-8, errorsignore) as f: for line in f: match line_pattern.search(line) if not match: continue timestamp, level, message match.groups() if level in (ERROR, WARN, CRITICAL): # 提取核心信息去掉具体参数值方便聚合 key_msg re.sub(r\d, #, message)[:80] counter[key_msg] 1 time_bucket[timestamp[:13]].update([key_msg]) # 按小时聚合 print(f日志文件: {log_file}) print(f共发现错误/警告类型 {len(counter)} 种Top {top_n} 如下) for msg, cnt in counter.most_common(top_n): print(f{cnt:6} 次 {msg}) print(\n按小时分布前5个最忙时段) for hour, cnt in time_bucket.most_common(5): total sum(cnt.values()) print(f{hour}:00 共 {total} 条) if __name__ __main__: main(sys.argv[1] if len(sys.argv) 1 else app.log)这个脚本里有个很关键的思路re.sub(r\d, #, message)把数字统一替换成#。为什么因为日志里常见的错误是连接超时、第3次重试失败、请求xxx失败如果把每一次的具体参数值都当成独立错误聚合后会出现几十条几乎长得一样的记录根本不是同一类错误。把数字归一化之后才能真正看到同类错误到底发生了多少次。4.4 脚本四重复文件清理平时备份、解压、传输文件很容易在硬盘里积累大量完全一样的文件。我写的去重脚本是这样工作的#!/usr/bin/env python3 # -*- coding: utf-8 -*- 查找目录中的重复文件按文件大小 MD5 哈希 import hashlib import os from collections import defaultdict from pathlib import Path def file_md5(path, chunk_size8192): h hashlib.md5() with open(path, rb) as f: while chunk : f.read(chunk_size): h.update(chunk) return h.hexdigest() def main(root_dir): root Path(root_dir) size_map defaultdict(list) # 第一轮按文件大小分组跳过小于1KB的文件 for file_path in root.rglob(*): if file_path.is_file(): size file_path.stat().st_size if size 1024: size_map[size].append(file_path) # 第二轮同尺寸文件再计算MD5 duplicates defaultdict(list) for size, files in size_map.items(): if len(files) 2: continue for f in files: md5 file_md5(f) duplicates[md5].append(str(f)) # 输出 count 0 for md5, paths in duplicates.items(): if len(paths) 2: continue count 1 print(fMD5: {md5}) for p in paths: print(f {p}) print(f共发现 {count} 组重复文件组请人工确认后删除多余副本) if __name__ __main__: main(sys.argv[1] if len(sys.argv) 1 else .)我特意没有在脚本里加自动删除功能这是刻意的。自动删除的风险非常大你以为重复文件可以删但有时候文件虽然内容一样其中一个位于另一个程序的硬连接引用路径里删除后可能影响程序运行。所以我的方案是脚本只负责找出来删除这一步永远由人脑决策。4.5 把这些脚本串成自动化组合拳单个脚本好用但真正让工作有如神助的是把它们组合起来。比如我每天的早间例行流程第一步下载目录归档脚本把昨晚下载的杂七杂八文件分类。第二步重复文件清理脚本识别和昨天重复的下载。第三步日志汇总脚本把昨晚运行的服务日志生成一个错误摘要。第四步端口检测脚本确认所有关键服务还活着。第五步如果一切正常系统自动给我发一封汇总邮件。在Windows上我用任务计划程序把这些脚本按时间串起来比如每天8点先跑归档8点5分跑日志汇总8点10分发邮件。在Linux或macOS上写一个cron表达式就行例如0 8 * * * cd /path/to/scripts python download_archiver.py 5 8 * * * cd /path/to/scripts python log_summary.py组合起来之后原本需要半小时的人工操作变成了开机后去看一眼邮件即可。这种感觉才是标题里如虎添翼的真实体验。5. 实测过程记录这三个坑几乎人人都会踩5.1 编码问题中文文件名与UTF-8的坑我印象最深的一次是给公司同事写批量重命名脚本运行到一半突然抛了UnicodeEncodeError。原因是Windows控制台默认编码可能是GBK当脚本打印中文路径时控制台无法正确编码就崩溃了。后来我的处理方案是两件事同时做第一在脚本文件头部明确# -*- coding: utf-8 -*-第二在读取文件列表时指定encodingutf-8并加上errorsignore兜底。具体到不同平台上Windows还可能需要sys.stdout.reconfigure(encodingutf-8)才能正确输出中文。另外一个隐蔽问题出现在CSV写入上Excel打开CSV时默认按ANSI读取直接用Python写入的UTF-8中文会被显示成乱码。解决方法是写入时加BOM头或者统一转成UTF-8-SIG编码。这是我做CSV拆分脚本时被领导亲自教育过一次的经历从那以后凡是给非技术同事用的CSV脚本我都会默认用utf-8-sig编码。5.2 路径与权限问题Windows和macOS表现差很多在Windows上跑文件遍历脚本时经常遇到PermissionError或者FileNotFoundError。有一次脚本处理一个被临时占用的文件读取时报另一个程序正在使用此文件整个脚本断掉了。后来我学会了把所有文件操作都包在try/except里并打印出一条日志说明跳过了哪个文件而不是直接让脚本崩溃。macOS和Linux上遇到的则是另一类问题目录里存在符号链接会让rglob在遍历时陷入循环比如链接指向上一层目录。我的脚本普遍增加了一个约定rglob(*)之后立刻过滤掉符号链接用file_path.is_file() and not file_path.is_symlink()来双保险。还有一个权限相关的心得清理类脚本不要用rm在Windows上尤其不要直接调os.remove来删只读文件否则会报错。我会先尝试chmod去除只读属性再执行删除但如果脚本要服务很多非技术同事最简单的方式是让脚本把待删文件列表输出到Excel让用户自己手动删。5.3 依赖库版本为什么脚本今天能跑明天就不能了项目里某个脚本依赖pandas某天同事升级了一下环境里的pandas同一个脚本开始报AttributeError。问题出在pandas的一个API在1.5之后改了行为append方法被弃用我用的concat方式也受到了其他影响。从那以后我给每一个重要脚本都准备了一个requirements.txt文件里面锁定了用到的第三方库版本。不要小看这个动作。假设你写了个脚本用了pypdf3.17.4半年后pypdf升级到4.x可能某些内部方法名就变了脚本直接无法导入。锁定版本之后部署到新机器时执行pip install -r requirements.txt就能原样复现当时能工作的环境。对于常更新的脚本我还会在文件顶部注释里写清楚最后验证日期和依赖列表隔几个月回头看一下成本极低但收益很大。6. 常见问题排错速查表我在用脚本的过程中积累了不少排错经验整理成下面这个速查表按现象-原因-排查思路的格式来写碰到问题可以先翻这一节现象可能原因排查与处理建议运行Python脚本提示ModuleNotFoundError第三方库没装或装到了别的虚拟环境先pip list查看已装包再pip install 包名中文文件名乱码或打印报错控制台编码与文件编码不一致Windows下先执行chcp 65001代码中指定utf-8Excel打开CSV中文乱码没有写入UTF-8 BOM写入编码换成utf-8-sig批量重命名时文件被覆盖没检查目标文件是否存在重命名前必须if target.exists()判断大文件处理时内存飙升一次性读入全部内容改用分块读取chunksize或for line in f扫描目录时陷入死循环有符号链接指向父目录遍历时过滤is_symlink()脚本弹文件占用错误文件正被其他程序打开对单文件操作加try/except失败则跳过定时任务里脚本运行失败工作目录不是脚本所在目录脚本内部用绝对路径不要依赖相对路径日志脚本统计出错日志格式不是预期格式先打印前几行原始日志核对正则表达式邮件脚本发送失败身份认证、SMTP端口被封检查授权码换587端口并启用SMTP_SSL除了表格里的这些我再补充一个独家排查技巧如果脚本逻辑复杂、不确定哪里出错了就在关键节点加print或logging打印中间变量不要直接删代码重写。打印一行日志的成本比重新调试低得多而且保留打印语句还能为以后排错留个线索。等确认一切正常再决定是否保留这些调试输出。很多人还会问脚本运行慢怎么办我的经验是优先优化IO而不是优化逻辑。比如合并CSV时多次writer.writerow逐行写入肯定比一次性writerows慢图片压缩时文件IO和压缩算法耗时往往比Python自身代码慢得多。先用time模块测量哪一段耗时长再针对性地优化不要一上来就上多线程或改复杂算法。实际上很多办公脚本几十兆数据用普通写法也就几秒钟完全够用。7. 最后分享两个我越用越顺手的小方法第一我为每一类脚本都建了别名放在Shell配置文件里。比如Windows下我用doskeymacOS和Linux下我用alias。archive就是下载目录归档dupfind就是查重复文件logs就是日志汇总。这样我不需要每次打python /path/to/script.py那么长一串命令敲几个字母加个路径参数就完事了。脚本的使用门槛越低你越愿意用它也越能感受到效率提升。第二我维护了一个脚本的脚本一个README.md文件和一个requirements.txt文件。README.md里按分类记录了所有脚本的功能、用法示例、依赖和已知限制requirements.txt记录了所有第三方库。坚持做这件事之后哪怕是半年之后换电脑、重新搭环境我也能一天之内把所有工具恢复到位不会出现脚本还在但忘了怎么用的尴尬。如果你打算照着这套思路搭建自己的脚本库我的建议是从最痛的一个场景切入看你哪项重复劳动最频繁就先写那一个脚本。不要试图一次搞定所有事情先把一个场景打通跑顺了再往下扩展。等到手里攒了几个能稳定运行的脚本之后你会发现自己对Python的兴趣会随之涨起来后面再写更大的工具也就不成问题了。
网站建设高端定制企业官网