为什么点击? — 单击文档
为什么点击?
有很多用于编写命令行实用程序的库; 为什么点击存在?
这个问题很容易回答:因为没有一个适用于 Python 的命令行实用程序可以勾选以下框:
- 可以无限制地懒惰组合
- 支持 Unix/POSIX 命令行约定的实现
- 支持从开箱即用的环境变量中加载值
- 支持自定义值提示
- 是完全可嵌套和可组合的
- 在 Python 2 和 3 中工作相同
- 支持开箱即用的文件处理
- 附带有用的通用助手(获取终端尺寸、ANSI 颜色、获取直接键盘输入、屏幕清除、查找配置路径、启动应用程序和编辑器等)
Click 有很多选择; 明显的是标准库中的 optparse
和 argparse
。 看看有没有其他东西引起你的共鸣。
Click 实际上实现了它自己的参数解析,并且不使用 optparse
或 argparse
跟随 optparse
解析行为。 它不基于 argparse
的原因是 argparse
不允许按设计正确嵌套命令,并且在涉及 POSIX 兼容参数处理时存在一些缺陷。
Click 旨在有趣且可定制,但又不过分灵活。 例如,帮助页面的可定制性受到限制。 此约束是有意的,因为 Click 承诺多个 Click 实例在串在一起时将继续按预期运行。
太多的可定制性会破坏这个承诺。
Click 是为了支持 [X33X]Flask 微框架生态系统而编写的,因为没有任何工具可以为其提供所需的功能。
要了解 Click 的全部内容,我强烈建议您查看 复杂应用程序 一章。
为什么不是 Argparse?
Click 内部基于 optparse
而不是 argparse
。 这是用户不必关心的实现细节。 Click 不是基于 argparse,因为它的一些行为使得处理任意命令行接口变得困难:
- argparse 具有内置行为来猜测某些内容是参数还是选项。 这在处理不完整的命令行时会成为一个问题; 如果不完全了解命令行,行为将变得不可预测。 这与 Click 向子解析器分派的野心背道而驰。
- argparse 不支持禁用散布参数。 没有这个特性,就不可能安全地实现 Click 的嵌套解析。
为什么不是Docopt等?
Docopt 和许多类似的工具在它们的工作方式上很酷,但是这些工具中很少有像 Click 那样处理命令嵌套和可组合性的。 据开发人员所知,Click 是第一个旨在创建超出系统本身支持的应用程序可组合性级别的 Python 库。
例如,Docopt 的作用是解析您的帮助页面,然后根据这些规则进行解析。 这样做的副作用是 docopt 在处理命令行界面方面非常严格。 docopt 的优点是它可以让您对帮助页面有很强的控制权; 缺点是由于这个原因,它无法为当前终端宽度重新包装您的输出,并且它使翻译变得困难。 最重要的是,docopt 仅限于基本解析。 它不处理参数调度和回调调用或类型。 这意味着除了基本的帮助页面之外,还需要编写大量代码来处理解析结果。
然而,最重要的是,它使可组合性变得困难。 虽然 docopt 确实支持分派到子命令,例如,它不直接支持基于可用内容的任何类型的自动子命令枚举,或者它不强制子命令以一致的方式工作。
这很好,但它与 Click 想要的工作方式不同。 Click 旨在通过执行以下操作来支持完全可组合的命令行用户界面:
- Click 不仅解析,它还分派到适当的代码。
- Click 有一个强大的调用上下文概念,它允许子命令响应来自父命令的数据。
- Click 为所有参数和命令提供强大的信息,因此它可以为完整的 CLI 生成统一的帮助页面,并根据需要帮助用户转换输入数据。
- Click 对什么类型有深刻的理解,如果出现问题,它可以向用户提供一致的错误消息。 由不同开发人员编写的子命令不会因为不同的错误消息而突然终止,因为它是手动处理的。
- Click 有足够的元信息可供其整个程序随着时间的推移而发展并改善用户体验,而无需迫使开发人员调整他们的程序。 例如,如果 Click 决定更改帮助页面的格式,则所有 Click 程序都将自动从中受益。
Click 的目标是制作可组合的系统。 而 docopt 的目标是构建最漂亮和手工制作的命令行界面。 这两个目标以微妙的方式相互冲突。 单击主动阻止人们实现某些模式以实现统一的命令行界面。 例如,作为开发人员,您在格式化帮助页面时几乎没有选择。
为什么要硬编码行为?
另一个问题是为什么 Click 放弃 optparse 并硬编码某些行为而不是保持可配置。 这有多种原因。 最大的一个是太多的可配置性使得很难实现一致的命令行体验。
最好的例子是 optparse 的 callback
功能,用于接受任意数量的参数。 由于命令行上的语法歧义,无法实现完全可变参数。 总是需要进行权衡,在 argparse
的情况下,这些权衡已经足够重要,以至于像 Click 这样的系统甚至无法在其上实现。
在这种特殊情况下,Click 尝试使用一些公认的范例来构建可以很好地记录和测试的命令行界面。
为什么没有自动更正?
问题出现了,为什么 Click 不自动更正参数,即使 optparse 和 argparse 也支持长参数的自动扩展。 这样做的原因是它是向后兼容性的责任。 如果人们开始依赖自动修改的参数,并且将来有人添加新参数,则脚本可能会停止工作。 这类问题很难发现,因此 Click 并没有试图对此感到神奇。
然而,这种行为可以在更高级别上实现以支持诸如显式别名之类的事情。 有关详细信息,请参阅 命令别名 。