前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用Click编写Python命令行工具

用Click编写Python命令行工具

作者头像
IT派
发布2018-07-30 11:29:05
3.3K0
发布2018-07-30 11:29:05
举报
文章被收录于专栏:IT派

在编写Python命令行(CLI)应用程序时,使用Click库进行参数解析的深入教程

Python通常被称为胶水语言,因为它非常灵活,并且能够与现有的程序很好地联结在一起。 这意味着很大一部分Python代码被编写为脚本和命令行界面(CLI)。

构建这些命令行界面和工具是非常强大的,因为它使得几乎所有的东西都可以自动化。 因此,随着时间的推移,CLI可能变得相当复杂。

通常从一个非常简单的脚本开始,运行这些python代码来完成一件特定的事情。例如:访问web API并将输出打印到控制台:

仅通过python print_user_agent.py你就可以运行它,它就会打印出 API调用的user-agent。

正如我所说,一个非常简单的脚本。

但是,当这样一个Python命令行脚本变得越来越复杂时,你有什么选择?

这就是我们将在整个教程中看到的内容。您将学习关于Python中构建CLI的基本知识,以及Click如何使其成为更好的体验。

我们将使用这些知识,并从简单的脚本一步一步地通过命令行参数、选项及有用的用法说明CLI。所有这些都使用了一个叫做click的框架。

在本教程的最后,你会知道:

  • 为什么click相比于argparse和optparse来说是一个更好的选择
  • 如何用它创建一个简单的CLI
  • 如何将强制命令行参数添加到您的脚本
  • 如何解析命令行标志和选项
  • 如何通过添加帮助(使用)文本,使命令行应用程序更加便于用户使用。

而且你也会看到如何用最少量的代码来实现所有的功能。

顺便说一下,本教程中的所有代码示例都使用Python 3.6。它们可能不适用于Python的早期版本,但是如果遇到任何麻烦,请在下面留言,我们将把它整理在一起。

让我们开始吧!

为什么要编写Python命令行脚本和工具?

上面的代码片段仅仅是一个例子,在现实生活中并不是很有用。我在Python开发人员的职业生涯中编写的脚本要复杂得多。它们通常帮助构建,测试和部署应用程序,并使流程可重复。

您可能有自己的经验,并知道这可能是我们日常工作的一大部分:有些脚本仍然保留在你们所构建的项目中,有些对其他团队或项目都有用,甚至可以扩展更多的功能。

在这些情况下,使脚本更加灵活或者可以使用命令行参数进行配置变得非常重要。它使得向脚本提供服务器名称,凭证或任何其他信息成为可能。

这就是像optparse和argparse这样的Python模块,让你的生活变得更轻松。但是,在我们仔细研究这些之前,让我们直接说一下我们的术语。

命令行接口的基础知识

命令行界面(CLI)以可执行文件的名称开头。您可以在控制台中键入它的名称,并访问脚本的主要入口点,例如pip。

根据CLI的复杂性,通常可以将参数传递给脚本,可以是:

1.参数,它是传递给脚本的必需参数。如果您不提供它,CLI将返回一个错误。例如,click是这个命令中的参数:pip install click。

2.或者它可以是一个选项,它是一个可选的(||)参数,结合名称和值部分,如--cache-dir ./my-cache。你告诉CLI应将./my-cache值用作缓存目录。

3.一个特殊选项是启用或禁用特定行为的标志。最常见的可能是 --help。您只需指定名称,CLI将在内部解释该值

使用更复杂的CLI(例如pip或Heroku Toolbelt),您可以访问集合入口的功能。它们通常被称为命令子命令

当你使用pip install安装Python包时,您可能已经使用了CLI。命令install会告诉CLI您将访问该功能来安装软件包,并使你能访问该特性的参数。

Python 3.x标准库中提供的命令行框架

将命令和参数添加到脚本中是非常强大的,但命令行的解析并不像您想象的那样直截了当。 你应该使用已经解决了这个问题的Python的软件包之一,来替代你自己写。

两个最着名的软件包是optparse和argparse。 它们是遵循“包含电池”原则的Python标准库的一部分。

他们大多提供相同的功能且使用代码非常相似。 最大的不同在于,optparse自Python 3.2以来已被弃用,argparse被认为是在Python中实现CLI的标准

你可以在Python文档中找到更多关于它们的详细信息,来让你知道一个argparse脚本是什么样子的,下面是一个例子:

click vs argparse:一个更好的选择?

你可能正在看上面的代码示例,在想“这些东西是什么意思?”这正是我在使用argparse遇到的一个问题:它不直观,很难阅读。

这就是为什么我爱上了click

click正在解决与optparse和argparse相同的问题,但使用方法稍微不同。它使用装饰器的概念。这需要命令是可以使用装饰器包装的函数。

丹写了一个很好的介绍,如果这是你第一次听到这个词,或许你想快速学习。

作者Armin Ronacher详细描述了他为什么写这个框架。您可以阅读文档中的“Why Click?”部分,我鼓励您看一下。

我使用click的主要原因是你可以使用少量代码轻松构建功能丰富的CLI。即使您的CLI增长并且变得更加复杂,代码也很容易阅读。

通过Click构建一个简单的Python命令行界面

我已经谈了很多CLI和框架。我们来看看用click来构建一个简单的CLI是什么意思。与本教程中的第一个示例类似,我们可以创建一个简单的基于click的CLI,它向控制台打印一些东西。这并不是很费力:

首先,我们现在不用担心最后两行,当文件作为脚本执行时,这只是Python(稍微不直观)的方式来运行主函数。

正如你所看到的,我们所要做的就是创建一个函数并添加@ click.command()装饰器。 这将它变成一个click命令,这是我们的脚本的主要入口点。 你现在可以在命令行上运行它,你会看到类似这样的东西:

click 之所以比较美观是因为,我们免费获得一些额外的功能。 我们没有实现任何帮助功能,但添加了--help选项,您将看到一个打印到命令行的基本帮助页面:

Click更实际的PythonCLI示例

现在你已经知道click是如何使得建立一个简单的CLI更容易了,我们将看一个稍微更现实的例子。我们将构建一个允许我们与Web API 进行交互的程序。最近每个人都会使用,它们让我们访问一些更酷的数据。

本教程其余部分将介绍的API是OpenWeatherMap API。 它提供当前天气以及特定位置的五天预报。 我们将从他们的API示例返回当前天气的位置。

在开始编写代码之前,我喜欢尝试使用API来更好地理解它是如何工作的。 我想你应该知道的一个工具是HTTPie,我们可以使用它来调用示例API并查看返回的结果。 你甚至可以尝试他们的在线终端来运行它,无需安装。

让我们来看看当我们将API中的位置设置为london时会发生什么:

如果你正在用这样的面孔查看屏幕?因为上面的例子包含一个API密钥,所以不要担心这是他们提供的示例API密钥。

上面例子中比较重要的一点是,我们发送两个查询参数(使用HTTPie时用==表示)来获取当前天气:

  • q是我们的地点名称;
  • appid是我们的API密钥。

这使我们可以使用Python和Requests库创建一个简单的实现(为简单起见,我们将忽略错误处理和失败请求)。

这个函数使用两个查询参数向天气API发出一个简单的请求。 它需要一个强制的参数location,它被假定为一个字符串。 我们还可以通过在函数调用中传递api_key来提供API密钥。 它是可选的,可以使用示例键作为默认值。

这里是我们目前伦敦的天气,形成Python REPL:

click 解析一个必选参数

简单的current_weather函数允许我们使用用户提供的自定义位置来构建我们的CLI。 我希望它能像这样工作:

你可能已经猜到了,这次调用的位置就是我之前介绍的一个参数。 这是因为它是我们天气CLI的强制性参数。

我们如何在Click中实现? 这很简单,我们使用一个名为参数的装饰器。 谁会想到?

我们先来看一个简单的例子,通过定义参数的位置来修改它。

你可以看到,我们所要做的就是添加一个额外的装饰器到我们的主要功能,并给它一个名字。Click使用该名称作为变量传递到包装函数的参数中。

在我们的例子中,命令行参数location的值将作为位置参数传递给主函数。有道理吧?

你也可以在你的名字中使用破折号( - ),例如api-key,在这个函数中,Click会将名字的中划线变为下划线。例如main(api_key)。

main的实现只需使用我们的current_weather函数来获取CLI调用者提供的位置的天气。 然后我们使用一个简单的打印语句输出天气信息||

完成!

如果这个打印语句对你来说看起来很奇怪,那是因为这是一种用Python 3.6+格式化字符串的新方法,称为f-string格式。 你应该查看 “Python中进行字符串格式化的4种主要方法”来了解更多。

cllick 解析可选参数

你可能已经找到了我们上面使用的示例API的一个小小的缺陷,你是一个聪明人

是的,这是一个静态的端点,从2017年1月起总是返回伦敦的天气。所以让我们用一个真实的API密钥来请求实际的API。

我们需要改变的第一件事是当前天气的URL端点。 我们可以通过在OpenWeatherMap文档中将current_weather函数中的url替换为端点来实现:

我们刚刚做出的更改将会破坏我们的CLI,因为默认API密钥对真实API无效。 该API将返回一个401 UNAUTHORIZED HTTP状态码。 不相信我? 这是证明:

所以让我们添加一个新的参数给我们的CLI,允许我们指定API密钥。 但首先,我们必须决定这应该是一个参数还是一个选项。

我们使它成为一个option,因为添加一个像--api-key这样的命名参数使得它更加明确和自描述。

以下是我认为用户应该运行它的方式:

很好很容易。 所以让我们看看我们如何将它添加到我们现有的click命令。

再来一次,我们正在为我们的main函数添加一个装饰器。 这一次,我们使用非常直观的命名@ click.option,并添加了我们的option名称,包括前双破折号( -- )。 正如你所看到的,我们也可以用一个短划线( - )来提供一个快捷方式来保存用户的一些输入。

我之前提到,click从较长的版本创建传递给主函数的参数。 在option的情况下,它将划破前面的破折号并将其变成snake_case的情况。 --api-key变成api_key。

我们必须做的最后一件事是将API密钥传递给我们的current_weather函数。

我们使CLI用户可以使用自己的密钥并查看任何位置:

看着我的窗口,我可以证实这是真的。

将自动生成的使用说明添加到您的Python命令行工具中

你可以安慰自己,你已经用最少量的Boilerplate_code构建了一个很棒的小CLI。但是在你休息或者享受一杯饮料之前, 通过添加一些文档,让我们确保一个新的用户能够知道如何运行我们的小CLI ...(不要跑,超级简单的。)

首先让我们来看看在我们做了所有更改之后,--help标志将会显示什么。 正如你所看到的,所有努力都不是白费力的:

我们想要解决的第一件事是我们的API密钥选项丢失的描述。 我们所要做的就是向@click.option装饰器提供一个帮助文本:

我们要做的第二个也是最后一个更改是添加整个click命令的文档。 而最简单的方式就是添加一个文档字符串到我们的main函数。 是的,我们应该这样做,所以这不是额外的工作:

综合起来,我们的天气工具得到了非常好的输出。

我希望在这一点上,你感觉到了当我第一次发现click时的感觉:

带有click的Python CLI:摘要&回顾

好的,我们已经在本教程中介绍了大量的内容。 现在是您为自己感到自豪的时候了。 以下是你所学到的:

  • 为什么click是一个更好的选择相对argparse和optparse
  • 如何用它创建一个简单的CLI
  • 如何将强制命令行参数添加到您的脚本
  • 如何解析命令行标志和选项;
  • 如何通过添加帮助(使用)文本使您的命令行应用程序更加用户友好

而所有这些都是用最少量的引用! 下面的完整代码示例说明了这一点。你可以自由地使用它来做你自己的实验

如果这启发了你,你应该看看click官方文档以获得更多的功能。 您也可以查看我在2016 PyCon US 关于click的介绍。或者留意我的后续教程,您将在其中学习如何为我们的天气CLI添加更多高级功能。

开心的CLI编码!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT派 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档