为什么Click?

有那么多库可以用来编写命令行实用程序;为什么Click“存在”?

这个问题很容易回答:因为没有一个针对python的命令行实用程序可以勾选以下框:

  • 不受限制地懒洋洋地沉着。

  • 支持实施Unix/POSIX命令行约定。

  • 支持开箱即用地从环境变量加载值。

  • 支持自定义值提示。

  • 是完全稳定和沉稳的。

  • 支持开箱即用的文件处理。

  • 附带有用的常用助手(获取端子尺寸、ANSI颜色、获取直接键盘输入、清除屏幕、查找配置路径、启动应用程序和编辑器等)。

点击有很多选择;显而易见的是 optparseargparse 从标准库。看看有没有其他东西能引起你的共鸣。

click实际上实现了它自己的参数解析,并且不使用 optparseargparse 跟随 optparse 分析行为。它不基于的原因 argparse 那是 argparse 不允许通过设计正确嵌套命令,并且在符合POSIX的参数处理方面存在一些缺陷。

Click被设计成有趣和可定制的,但不是过于灵活。例如,帮助页面的可定制性受到限制。这个约束是有意的,因为Click承诺多个Click实例在串在一起时将继续按预期工作。

太多的可定制性会破坏这一承诺。

已写入Click以支持 Flask 微框架生态系统,因为没有工具能够提供它所需要的功能。

为了了解Click的所有功能,我强烈建议您查看 复杂的应用 章。

为什么不argparse?

点击在内部是基于 optparse 而不是 argparse 。这是用户不必关心的实现细节。点击不是基于 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主动阻止人们实现某些模式。例如,作为一个开发人员,在格式化帮助页面时,您几乎没有选择余地。

为什么要硬编码行为?

另一个问题是为什么Click远离optparse并硬编码某些行为,而不是保持可配置性。这有多种原因。最大的一个问题是,过多的可配置性使得很难获得一致的命令行体验。

最好的例子是Optparse的 callback 接受任意数量参数的功能。由于命令行上的语法歧义,无法实现完全可变的参数。总有一些需要权衡的地方 argparse 这些权衡已经足够关键了,像click这样的系统甚至不能在上面实现。

在这种特定的情况下,Click尝试保留一些公认的用于构建命令行接口的范例,这些范例可以很好地记录和测试。

为什么不自动更正?

问题来了,为什么Click不自动更正参数,因为即使是optparse和 argparse 支持长参数的自动扩展。这样做的原因是这是一种向后兼容的倾向。如果人们开始依赖自动修改的参数,而将来有人添加了新参数,脚本可能会停止工作。这类问题很难发现,所以Click并没有试图在这方面变得神奇。

但是,这种行为可以在更高的级别上实现,以支持诸如显式别名之类的事情。有关详细信息,请参阅 命令别名 .