在我的职业生涯中,我写过、用过和看到过很多随意的脚本。一些人需要半自动化完成任务,于是它们诞生了。一段时间后,它们变得越来越大。它们在一生中可能转手很多次。我常常希望这些脚本提供更多的命令行工具式的感觉。但是,从一次性脚本到合适的工具,真正提高质量水平有多难呢?事实证明这在 Python 中并不难。
搭建骨架脚本
在本文中,我将从一小段 Python 代码开始。我将把它应用到 scaffold
模块中,并使用 click
库扩展它以接受命令行参数。
#!/usr/bin/python from glob import glob from os.path import join, basename from shutil import move from datetime import datetime from os import link, unlink LATEST = 'latest.txt' ARCHIVE = '/Users/mark/archive' INCOMING = '/Users/mark/incoming' TPATTERN = '%Y-%m-%d' def transmogrify_filename(fname): bname = basename(fname) ts = datetime.now().strftime(TPATTERN) return '-'.join([ts, bname]) def set_current_latest(file): latest = join(ARCHIVE, LATEST) try: unlink(latest) except: pass link(file, latest) def rotate_file(source): target = join(ARCHIVE, transmogrify_filename(source)) move(source, target) set_current_latest(target) def rotoscope(): file_no = 0 folder = join(INCOMING, '*.txt') print(f'Looking in {INCOMING}') for file in glob(folder): rotate_file(file) print(f'Rotated: {file}') file_no = file_no + 1 print(f'Total files rotated: {file_no}') if __name__ == '__main__': print('This is rotoscope 0.4.1. Bleep, bloop.') rotoscope()
本文所有没有在这里插入显示的代码示例,你都可以在 https://www.php.cn/link/575afbdca5a101e3088b2b6554398b0c 中找到特定版本的代码。该仓库中的每个提交都描述了本文操作过程中一些有意义的步骤。
这个片段做了几件事:
- 检查
INCOMING
指定的路径中是否有文本文件 - 如果存在,则使用当前时间戳创建一个新文件名,并将其移动到
ARCHIVE
- 删除当前的
ARCHIVE/latest.txt
链接,并创建一个指向刚刚添加文件的新链接
作为一个示例,它很简单,但它会让你理解这个过程。
使用 Pyscaffold 创建应用程序
首先,你需要安装 scaffold
、click
和 tox
Python 库。
$ python3 -m pip install scaffold click tox
安装 scaffold
后,切换到示例的 rotoscope
项目所在的目录,然后执行以下命令:
$ putup rotoscope -p rotoscope --force --no-skeleton -n rotoscope -d 'Move some files around.' -l GLWT -u http://codeberg.org/ofosos/rotoscope --save-config --pre-commit --markdown
Pyscaffold 会重写我的 README.md
,所以从 Git 恢复它:
$ git checkout README.md
Pyscaffold 在文档中说明了如何设置一个完整的示例项目,我不会在这里介绍,你之后可以探索。除此之外,Pyscaffold 还可以在项目中为你提供持续集成(CI)模板:
- 打包: 你的项目现在启用了 PyPi,所以你可以将其上传到一个仓库并从那里安装它。
- 文档: 你的项目现在有了一个完整的文档文件夹层次结构,它基于 Sphinx,包括一个readthedocs.org 构建器。
- 测试: 你的项目现在可以与 tox 一起使用,测试文件夹包含运行基于 pytest 的测试所需的所有样板文件。
- 依赖管理: 打包和测试基础结构都需要一种管理依赖关系的方法。
setup.cfg
文件解决了这个问题,它包含所有依赖项。 - 预提交钩子: 包括 Python 源代码格式工具 black 和 Python 风格检查器 flake8。
查看测试文件夹并在项目目录中运行 tox
命令,它会立即输出一个错误:打包基础设施无法找到相关库。
现在创建一个 Git
标记(例如 v0.2
),此工具会将其识别为可安装版本。在提交更改之前,浏览一下自动生成的 setup.cfg
并根据需要编辑它。对于此示例,你可以修改 LICENSE
和项目描述,将这些更改添加到 Git 的暂存区,我必须禁用预提交钩子,然后提交它们。否则,我会遇到错误,因为 Python 风格检查器 flake8 会抱怨糟糕的格式。
$ PRE_COMMIT_ALLOW_NO_CONFIG=1 git commit
如果这个脚本有一个入口点,用户可以从命令行调用,那就更好了。现在,你只能通过找 .py
文件并手动执行它来运行。幸运的是,Python 的打包基础设施有一个很好的“罐装”方式,可以轻松地进行配置更改。将以下内容添加到 setup.cfg
的 options.entry_points
部分:
console_scripts = roto = rotoscope.rotoscope:rotoscope
这个更改会创建一个名为 roto
的 shell 命令,你可以使用它来调用 rotoscope 脚本,使用 pip
安装 rotoscope 后,可以使用 roto
命令。
就是这样,你可以从 Pyscaffold 免费获得所有打包、测试和文档设置。你还获得了一个预提交钩子来保证(大部分情况下)你按照设定规则提交。
CLI 工具化
现在,一些值会硬编码到脚本中,它们作为命令 参数 会更方便。例如,将 INCOMING
常量作为命令行参数会更好。
首先,导入 click 库,使用 Click 提供的命令装饰器对 rotoscope()
方法进行装饰,并添加一个 Click 传递给 rotoscope
函数的参数。Click 提供了一组验证器,因此要向参数添加一个路径验证器。Click 还方便地使用函数的内嵌字符串作为命令行文档的一部分。所以你最终会得到以下方法签名:
@click.command() @click.argument('incoming', type=click.Path(exists=True)) def rotoscope(incoming): """ Rotoscope 0.4 - Bleep, blooop. Simple sample that move files. """
主函数会调用 rotoscope()
,它现在是一个 Click 命令,不需要传递任何参数。
选项也可以使用 环境变量 自动填充。例如,将 ARCHIVE
常量改为一个选项:
@click.option('archive', '--archive', default='/Users/mark/archive', envvar='ROTO_ARCHIVE', type=click.Path())
使用相同的路径验证器。这一次,让 Click 填充环境变量,如果环境变量没有提供任何内容,则默认为旧常量的值。
Click 可以做更多的事情,它有彩色的控制台输出、提示和子命令,可以让你构建复杂的 CLI 工具。浏览 Click 文档会发现它的更多功能。
现在添加一些测试。
测试
Click 对使用 CLI 运行器 运行端到端测试 提供了一些建议。你可以用它来实现一个完整的测试(在 示例项目 中,测试在 tests
文件夹中。)
测试位于测试类的一个方法中。大多数约定与我在其他 Python 项目中使用的非常接近,但有一些细节,因为 rotoscope 使用 click
。在 test
方法中,我创建了一个 CliRunner
。测试使用它在一个隔离的文件系统中运行此命令。然后测试在隔离的文件系统中创建 incoming
和 archive
目录和一个虚拟的 incoming/test.txt
文件,然后它调用 CliRunner,就像你调用命令行应用程序一样。运行完成后,测试会检查隔离的文件系统,并验证 incoming
为空,并且 archive
包含两个文件(最新链接和存档文件)。
from os import listdir, mkdir from click.testing import CliRunner from rotoscope.rotoscope import rotoscope class TestRotoscope: def test_roto_good(self, tmp_path): runner = CliRunner() with runner.isolated_filesystem(temp_dir=tmp_path) as td: mkdir("incoming") mkdir("archive") with open("incoming/test.txt", "w") as f: f.write("hello") result = runner.invoke(rotoscope, ["incoming", "--archive", "archive"]) assert result.exit_code == 0 print(td) incoming_f = listdir("incoming") archive_f = listdir("archive") assert len(incoming_f) == 0 assert len(archive_f) == 2
要在控制台上执行这些测试,在项目的根目录中运行 tox
。
在执行测试期间,我在代码中发现了一个错误。当我进行 Click 转换时,rotoscope
只是取消了最新文件的链接,无论它是否存在。测试从一个新的文件系统(不是我的主文件夹)开始,很快就失败了。我可以通过在一个很好的隔离和自动化测试环境中运行来防止这种错误。这将避免很多“它在我的机器上正常工作”的问题。
搭建骨架脚本和模块
本文到此结束,我们可以使用 scaffold
和 click
完成一些高级操作。有很多方法可以升级一个普通的 Python 脚本,甚至可以将你的简单实用程序变成成熟的 CLI 工具。
以上是将你的 Python 脚本转换为命令行程序的详细内容。更多信息请关注PHP中文网其他相关文章!

Python更易学且易用,C 则更强大但复杂。1.Python语法简洁,适合初学者,动态类型和自动内存管理使其易用,但可能导致运行时错误。2.C 提供低级控制和高级特性,适合高性能应用,但学习门槛高,需手动管理内存和类型安全。

Python和C 在内存管理和控制方面的差异显着。 1.Python使用自动内存管理,基于引用计数和垃圾回收,简化了程序员的工作。 2.C 则要求手动管理内存,提供更多控制权但增加了复杂性和出错风险。选择哪种语言应基于项目需求和团队技术栈。

Python在科学计算中的应用包括数据分析、机器学习、数值模拟和可视化。1.Numpy提供高效的多维数组和数学函数。2.SciPy扩展Numpy功能,提供优化和线性代数工具。3.Pandas用于数据处理和分析。4.Matplotlib用于生成各种图表和可视化结果。

选择Python还是C 取决于项目需求:1)Python适合快速开发、数据科学和脚本编写,因其简洁语法和丰富库;2)C 适用于需要高性能和底层控制的场景,如系统编程和游戏开发,因其编译型和手动内存管理。

Python在数据科学和机器学习中的应用广泛,主要依赖于其简洁性和强大的库生态系统。1)Pandas用于数据处理和分析,2)Numpy提供高效的数值计算,3)Scikit-learn用于机器学习模型构建和优化,这些库让Python成为数据科学和机器学习的理想工具。

每天学习Python两个小时是否足够?这取决于你的目标和学习方法。1)制定清晰的学习计划,2)选择合适的学习资源和方法,3)动手实践和复习巩固,可以在这段时间内逐步掌握Python的基本知识和高级功能。

Python在Web开发中的关键应用包括使用Django和Flask框架、API开发、数据分析与可视化、机器学习与AI、以及性能优化。1.Django和Flask框架:Django适合快速开发复杂应用,Flask适用于小型或高度自定义项目。2.API开发:使用Flask或DjangoRESTFramework构建RESTfulAPI。3.数据分析与可视化:利用Python处理数据并通过Web界面展示。4.机器学习与AI:Python用于构建智能Web应用。5.性能优化:通过异步编程、缓存和代码优

Python在开发效率上优于C ,但C 在执行性能上更高。1.Python的简洁语法和丰富库提高开发效率。2.C 的编译型特性和硬件控制提升执行性能。选择时需根据项目需求权衡开发速度与执行效率。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

Dreamweaver Mac版
视觉化网页开发工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3汉化版
中文版,非常好用

WebStorm Mac版
好用的JavaScript开发工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。