搜索
查看: 4046|回复: 8

怎样编写实用小工具

[复制链接]
发表于 2022-9-1 17:15:18 | 显示全部楼层 |阅读模式
本帖最后由 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]

怎样编写实用小工具.pdf

110.84 KB, 下载次数: 333

评分

1

查看全部评分

回复

使用道具 举报

 楼主| 发表于 2022-9-1 17:43:54 | 显示全部楼层
本帖最后由 wdscxsj 于 2022-9-1 17:53 编辑

这后面一堆图片是怎么回事,不是我上传的,好像也改不了……

怎样编写实用小工具.pdf

110.84 KB, 下载次数: 325

回复

使用道具 举报

发表于 2022-9-1 17:48:43 | 显示全部楼层
wdscxsj 发表于 2022-9-1 17:43
这后面一堆图片是怎么回事,不是我上传的,好像也改不了……

帮你编辑掉了。
回复

使用道具 举报

 楼主| 发表于 2022-9-1 17:50:14 | 显示全部楼层
谢谢!我再试试是不是 Markdown 编辑器的问题。
回复

使用道具 举报

发表于 2022-9-1 20:32:15 | 显示全部楼层
Python 确实神奇。
但……我只会用它来批量转换文件格式
回复

使用道具 举报

发表于 2022-9-1 20:37:09 | 显示全部楼层
目前还没有自己编程的需求。
先看看的!!
回复

使用道具 举报

发表于 2022-9-2 09:49:47 | 显示全部楼层
我觉得,这个帖子如果是原创还可以,但最好到更对口,更专业的论坛发表,这样可以有最好的反馈。
如果是转帖,那……,转贴的技术有问题有点大。
回复

使用道具 举报

 楼主| 发表于 2022-9-2 14:36:50 | 显示全部楼层
OOO 发表于 2022-9-1 20:32
Python 确实神奇。
但……我只会用它来批量转换文件格式

改扩展名还是转换图片格式啊?只改扩展名的话,这样比较方便:
ren *.txt *.log
回复

使用道具 举报

联系我们(Contact)|手机版|萝卜头IT论坛 ( 苏ICP备15050961号-1 )

GMT+8, 2024-11-5 01:36 , Processed in 0.095804 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表