|
本帖最后由 wdscxsj 于 2022-9-1 17:52 编辑
[md]最近对 Python 感兴趣的坛友好像挺多,刚才写了个短文,提供一点实践思路,供大家参考。楼下的PDF版有代码高亮,可能更易读。
# 怎样编写实用小工具
## 编程干啥
会编程的一大好处是**让电脑替你做事**。但是初学者限于所见,经常想不出有用的需求,弄几下就凉了,自己也很不满意。
有用的软件应该是**活的**,输入不同的要求都能得出有效的结果。比如最常见的记事本,可以任意写,随便保存。再比如计算器,加减乘除样样行。这些常用软件看似平凡,实际代表了不同方向的几大类需求。
自己编写的实用小工具,可以针对日常使用电脑的频繁操作,想办法把它自动化。有了这个底子,以后的学习工作中遇到问题,自然而然就能想到需要编写(或者寻找)怎样的辅助性工具,提高效率。
**动脑想**是构造合理的需求、提出方案,**动手做**是一步步完成目标,需要不断改进方案、评估工作量、确保质量,二者都很重要。
作为示例,下面简述一个小工具的实现过程。因为没什么技术难度,也为了节约篇幅,主要是指出一些值得思考的地方,看看它是怎样从模糊的“我想要”逐渐具体化的。代码以 Python 为例。
## 初始构想
随便一台经常使用的电脑,应该都保存了很多资料。多到漫山遍野,还在不断增加,但是反复用到的也就几十个。
要是它们整整齐齐该有多好啊!但打死我也不会去整理的……就算拼死弄好了,再放东西还不是慢慢变乱?
我想要一个……会按我心意归类文件的电脑?而且想找啥会自动蹦出来?所以要先研究人工智能和脑机?
太不切实际啦。
那,一个**靠谱的需求**其实是,我把常用的那几十个文件整理出来,也不用把它们放一堆,只要弄个小工具,想用哪个自动替我打开就好。以后有常用的就增加,不再常用的就删掉。
有没有现成的呢?Everything 是搜文件的利器,但是需要写文件名,切输入法。Clavier 之类的可以配置,但有点麻烦。有不少自称神器的,界面整得花花,纯属大炮打蚊子,还不知道会不会偷我数据。机智一点可以维护一堆快捷方式,但是文件一改哪个不对也不容易检查。
**易配置、易调用、跨平台、改细节**。在一个具体需求面前,很多“成熟软件”用这四个显微镜一看,经常不如自己写的一个小脚本好用。
## 先弄原型
我要写个工具,叫它 qo(Quickly Open)。如果想看《三国志》,可以 Win+R 一下,输入 `qo sgz` 回车,就给我打开。
这个嘛,其实很好办:
```py
import os
import sys
mydocs = {
'sgz': r'C:\Books\史\二十四史\三国志.陈寿撰 裴松之注.2011.pdf',
# 其它...
}
def main():
for name in sys.argv[1:]:
path = mydocs.get(name)
if path:
os.startfile(path)
if __name__ == '__main__':
main()
```
其中省略了不少细节,比如没输对的名字应该适当提示,不存在的文件也要有反馈等等。但作为“快速打开”的小工具,这就能用了。
然后把它放在环境变量 PATH 下的一个文件夹里,建议新建一个放在末尾(不明白这句话就查一下)。但是“运行”对话框不能不带扩展名直接运行 .py 文件,所以最好是另写一个 qo.bat,放在 PATH 文件夹里,这是一个常用技巧:
```bat
"path\to\python.exe" "path\to\qo.py" %*
```
试一下确实很方便。
qo 用一个 dict 管理了所有助记名和文件路径,有这个名字就打开。它的好处是,助记名可以自己起,而且配置很直观,不满意随时改。
## 持续改进
名字再好记,多了总会忘。能给点提示多好?比如 `qo -l` 就列出所有助记名,`qo -L` 就把文件路径也列出来。加了选项,用 `sys.argv` 就显得麻烦了,`argparse` 比较便利。
```py
import argparse
def main():
parser = argparse.ArgumentParser(description='qo: quickly open anything!')
parser.add_argument('-l', action='store_true', help='list mnemonics')
parser.add_argument('-L', action='store_true', help='list mnemonics with file paths')
args = parser.parse_args()
if args.l:
print(' '.join(mydocs.keys()))
return
... # if args.L
```
这个代码仍然只是示意,每个选项对应的功能最好用单独的函数实现。如果不喜欢命令行窗口,可以显示在对话框里。
用着用着,要是有的文件变了怎么办?所以要能校验文件路径是否有效:`qo -v`。
```py
parser.add_argument('-v', action='store_true', help='verify file paths')
...
if args.v:
for name, path in mydocs.items():
if not os.path.isfile(path):
print(f'missing: {name} => {path}')
return
```
自己写的小工具,经常用就会发现,可改进的地方有很多。**越经常用,对别人越有用,活力就越大,说明越成功**。持续改进,它就活得更健康。
比如,`-l` 和 `-L` 选项只列出全部就有点浪费了,一般不想看一大堆输出。可以让它们接受一个可选的搜索参数,匹配的才列出来。还可以加一个选项,支持正则表达式匹配。
如果文件名比较长,匹配的部分不容易一眼看出来。可以用 colorama 这个第三方库高亮显示。
`os.startfile()` 相当于双击打开。如果有的文件不想用关联的程序打开,或者需要指定运行参数,就可以把 `mydocs` 拆开管理。
```py
import subprocess
rundocs = {
'name1': ['prog1', 'arg1', 'arg2'],
# ...
}
...
cmd = rundocs.get(name)
if cmd:
subprocess.call(cmd)
```
配置的部分慢慢变长了,继续放在代码里就有点笨重。单独存成配置文件更容易管理,比如 json、yaml 之类的格式,一般放在 home 文件夹里(`os.path.expanduser()`),或者脚本文件的旁边。
如果文件管理的意识比较好,需要快速访问的文件全部放在一个顶层文件夹内,就可以把它配置为“根目录”,其它文件的路径相对它进行计算。这样,只复制这个文件夹就备份了“所有资料”,如果在别的电脑上使用,只修改一个路径(也可以作为命令行选项)就还原了自己熟悉的环境,甚至 Linux 系统也无妨。
实现的功能一多,难免有些边边角角考虑不全,或者后面的把前面的改坏了。所以还应该编写测试代码,确保新功能正确严谨,每次的修改都基础稳固。
以上种种,是成品软件不容易精确提供的,自己实现起来并不困难,又很实用,非常划算。工具虽小,从需求到实现是个完整流程,可以喻大。电脑是游戏机、纯消费品、不务正业,这种观念已经远远落后于时代。找到了合适的方向,就可以用它形成价值,改进自己的学习和生活。
[/md] |
评分
-
1
查看全部评分
-
|