有时,完成工作的正确工具是命令行应用程序。 命令行应用程序是您可以与之交互并从 shell 或终端等运行的程序。 您可能已经熟悉 Git 和 Curl 等命令行应用程序。
当您想要连续多次或定期运行一段代码时,命令行应用程序非常有用。 Django 开发人员运行 ./manage.py runserver
等命令来启动他们的 Web 服务器; Docker 开发人员运行 docker-compose up
来启动他们的容器。 您可能想要编写命令行应用程序的原因与您可能想要编写代码的原因一样多种多样。
对于本月的 Python 专栏,我们有三个库要推荐给希望编写自己的命令行工具的 Pythonistas。
Click
Click 是我们最喜欢的用于命令行应用程序的 Python 包。 它
- 具有包含示例的出色文档
- 包含将您的应用程序打包为 Python 应用程序的说明,以便更易于运行
- 自动生成有用的帮助文本
- 允许您堆叠可选和必需的参数,甚至 多个命令
- 具有用于编写管理命令的 Django 版本 (
django-click
)
Click 使用其 @click.command()
将函数声明为命令并指定必需或可选的参数。
# hello.py
import click
@click.command()
@click.option('--name', default='', help='Your name')
def say_hello(name):
click.echo("Hello {}!".format(name))
if __name__ == '__main__':
say_hello()
@click.option()
装饰器声明一个 可选参数,@click.argument()
装饰器声明一个 必需参数。 您可以通过堆叠装饰器来组合可选和必需的参数。 echo()
方法将结果打印到控制台。
$ python hello.py --name='Lacey'
Hello Lacey!
Docopt
Docopt 是一个命令行应用程序解析器,有点像命令行应用程序的 Markdown。 如果您喜欢在编写应用程序时编写文档,那么 Docopt 在本文中提供的选项中具有格式最好的帮助文本。 它不是我们最喜欢的命令行应用程序库,因为它的文档会立即将您推入深水区,这使得入门有点困难。 尽管如此,它是一个轻量级的库,非常流行,尤其是在异常漂亮的文档对您很重要的情况下。
Docopt 非常特别,您需要以特定的方式格式化文件顶部的必需文档字符串。 文档字符串中工具名称之后的顶部元素必须是“Usage”,它应列出您希望命令被调用的方式(例如,单独调用、带有参数调用等)。 用法应包括 help
和 version
标志。
文档字符串中的第二个元素应为“Options”,它应提供有关您在“Usage”中标识的选项和参数的更多信息。 文档字符串的内容将成为帮助文本的内容。
"""HELLO CLI
Usage:
hello.py
hello.py <name>
hello.py -h|--help
hello.py -v|--version
Options:
<name> Optional name argument.
-h --help Show this screen.
-v --version Show version.
"""
from docopt import docopt
def say_hello(name):
return("Hello {}!".format(name))
if __name__ == '__main__':
arguments = docopt(__doc__, version='DEMO 1.0')
if arguments['<name>']:
print(say_hello(arguments['<name>']))
else:
print(arguments)
在其最基本的层面上,Docopt 旨在将您的参数作为键值对返回到控制台。 如果我在不指定名称的情况下调用上述命令,我会得到一个字典
$ python hello.py
{'--help': False,
'--version': False,
'<name>': None}
这表明我没有输入 help
或 version
标志,并且 name
参数为 None
。
但是如果我使用名称调用它,say_hello
函数将执行。
$ python hello.py Jeff
Hello Jeff!
Docopt 允许必需参数和可选参数,并且每种参数都有不同的语法约定。 必需参数应以 ALLCAPS
或 <尖括号>
表示,选项应以双破折号或单破折号表示,例如 --name
。 在文档中阅读有关 Docopt 模式的更多信息。
Fire
Fire 是一个用于编写命令行应用程序的 Google 库。 当您的命令需要采用更复杂的参数或处理 Python 对象时,我们特别喜欢它,因为它会尝试智能地处理解析您的参数类型。
Fire 的 文档包含大量示例,但我希望文档的组织性更好一些。 Fire 可以处理 一个文件中的多个命令,作为 对象的方法的命令和 分组命令。
它的缺点是它向控制台提供的文档。 命令上的文档字符串不会出现在帮助文本中,并且帮助文本不一定标识参数。
import fire
def say_hello(name=''):
return 'Hello {}!'.format(name)
if __name__ == '__main__':
fire.Fire()
参数是必需的还是可选的,取决于您是否在函数或方法定义中为它们指定了默认值。 要调用此命令,您必须指定文件名和函数名称,更像 Click 的语法
$ python hello.py say_hello Rikki
Hello Rikki!
您也可以将参数作为标志传递,例如 --name=Rikki
。
奖励:打包!
Click 包含有关使用 setuptools
打包命令的说明(并强烈建议您遵循这些说明)。
要打包我们的第一个示例,请将此内容添加到您的 setup.py
文件
from setuptools import setup
setup(
name='hello',
version='0.1',
py_modules=['hello'],
install_requires=[
'Click',
],
entry_points='''
[console_scripts]
hello=hello:say_hello
''',
)
在您看到 hello
的任何地方,替换您的模块名称,但省略 .py
扩展名。 在您看到 say_hello
的任何地方,替换您的函数名称。
然后,运行 pip install --editable
以使您的命令可用于命令行。
您现在可以像这样调用您的命令
$ hello --name='Jeff'
Hello Jeff!
通过打包您的命令,您可以省略在控制台中键入 python hello.py --name='Jeff'
的额外步骤,并节省多次击键。 这些说明可能也适用于我们提到的其他库。
2 条评论