translated

This commit is contained in:
jiandongzhu 2018-07-03 12:23:40 +08:00
parent 070c2b5ad1
commit 497c8896a4
2 changed files with 196 additions and 271 deletions

View File

@ -1,271 +0,0 @@
translating----hoppipolla-
3 Python command-line tools
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc-lead-tool-box.png?itok=NrJYb417)
This article was co-written with [Lacey Williams Henschel][1].
Sometimes the right tool for the job is a command-line application. A command-line application is a program that you interact with and run from something like your shell or Terminal. [Git][2] and [Curl][3] are examples of command-line applications that you might already be familiar with.
Command-line apps are useful when you have a bit of code you want to run several times in a row or on a regular basis. Django developers run commands like `./manage.py runserver` to start their web servers; Docker developers run `docker-compose up` to spin up their containers. The reasons you might want to write a command-line app are as varied as the reasons you might want to write code in the first place.
For this month's Python column, we have three libraries to recommend to Pythonistas looking to write their own command-line tools.
### Click
[Click][4] is our favorite Python package for command-line applications. It:
* Has great documentation filled with examples
* Includes instructions on packaging your app as a Python application so it's easier to run
* Automatically generates useful help text
* Lets you stack optional and required arguments and even [several commands][5]
* Has a Django version ([][6]
`django-click`
) for writing management commands
Click uses its `@click.command()` to declare a function as a command and specify required or optional arguments.
```
# 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__':
    hello()
```
The `@click.option()` decorator declares an [optional argument][7], and the `@click.argument()` decorator declares a [required argument][8]. You can combine optional and required arguments by stacking the decorators. The `echo()` method prints results to the console.
```
$ python hello.py --name='Lacey'
Hello Lacey!
```
### Docopt
[Docopt][9] is a command-line application parser, sort of like Markdown for your command-line apps. If you like writing the documentation for your apps as you go, Docopt has by far the best-formatted help text of the options in this article. It isn't our favorite command-line app library because its documentation throws you into the deep end right away, which makes it a little more difficult to get started. Still, it's a lightweight library that is very popular, especially if exceptionally nice documentation is important to you.
`help` and `version` flags.
Docopt is very particular about how you format the required docstring at the top of your file. The top element in your docstring after the name of your tool must be "Usage," and it should list the ways you expect your command to be called (e.g., by itself, with arguments, etc.). Usage should includeandflags.
The second element in your docstring should be "Options," and it should provide more information about the options and arguments you identified in "Usage." The content of your docstring becomes the content of your help text.
```
"""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)
```
At its most basic level, Docopt is designed to return your arguments to the console as key-value pairs. If I call the above command without specifying a name, I get a dictionary back:
```
$ python hello.py
{'--help': False,
 '--version': False,
 '<name>': None}
```
This shows me I did not input the `help` or `version` flags, and the `name` argument is `None`.
But if I call it with a name, the `say_hello` function will execute.
```
$ python hello.py Jeff
Hello Jeff!
```
Docopt allows both required and optional arguments and has different syntax conventions for each. Required arguments should be represented in `ALLCAPS` or in `<carets>`, and options should be represented with double or single dashes, like `--name`. Read more about Docopt's [patterns][10] in the docs.
### Fire
[Fire][11] is a Google library for writing command-line apps. We especially like it when your command needs to take more complicated arguments or deal with Python objects, as it tries to handle parsing your argument types intelligently.
Fire's [docs][12] include a ton of examples, but I wish the docs were a bit better organized. Fire can handle [multiple commands in one file][13], commands as methods on [objects][14], and [grouping][15] commands.
Its weakness is the documentation it makes available to the console. Docstrings on your commands don't appear in the help text, and the help text doesn't necessarily identify arguments.
```
import fire
def say_hello(name=''):
    return 'Hello {}!'.format(name)
if __name__ == '__main__':
  fire.Fire()
```
Arguments are made required or optional depending on whether you specify a default value for them in your function or method definition. To call this command, you must specify the filename and the function name, more like Click's syntax:
```
$ python hello.py say_hello Rikki
Hello Rikki!
```
You can also pass arguments as flags, like `--name=Rikki`.
### Bonus: Packaging!
Click includes instructions (and highly recommends you follow them) for [packaging][16] your commands using `setuptools`.
To package our first example, add this content to your `setup.py` file:
```
from setuptools import setup
setup(
    name='hello',
    version='0.1',
    py_modules=['hello'],
    install_requires=[
        'Click',
    ],
    entry_points='''
        [console_scripts]
        hello=hello:say_hello
    ''',
)
```
Everywhere you see `hello`, substitute the name of your module but omit the `.py` extension. Where you see `say_hello`, substitute the name of your function.
Then, run `pip install --editable` to make your command available to the command line.
You can now call your command like this:
```
$ hello --name='Jeff'
Hello Jeff!
```
By packaging your command, you omit the extra step in the console of having to type `python hello.py --name='Jeff'` and save yourself several keystrokes. These instructions will probably also work for the other libraries we mentioned.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/5/3-python-command-line-tools
作者:[Jeff Triplett][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/laceynwilliams
[1]:https://opensource.com/users/laceynwilliams
[2]:https://git-scm.com/
[3]:https://curl.haxx.se/
[4]:http://click.pocoo.org/5/
[5]:http://click.pocoo.org/5/commands/
[6]:https://github.com/GaretJax/django-click
[7]:http://click.pocoo.org/5/options/
[8]:http://click.pocoo.org/5/arguments/
[9]:http://docopt.org/
[10]:https://github.com/docopt/docopt#usage-pattern-format
[11]:https://github.com/google/python-fire
[12]:https://github.com/google/python-fire/blob/master/docs/guide.md
[13]:https://github.com/google/python-fire/blob/master/docs/guide.md#exposing-multiple-commands
[14]:https://github.com/google/python-fire/blob/master/docs/guide.md#version-3-firefireobject
[15]:https://github.com/google/python-fire/blob/master/docs/guide.md#grouping-commands
[16]:http://click.pocoo.org/5/setuptools/

View File

@ -0,0 +1,196 @@
3个 Python 命令行工具
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc-lead-tool-box.png?itok=NrJYb417)
这篇文章是与 [Lacey Williams Hensche][1] 共同撰写的。
有时对于某项工作来说一个命令行工具就足以胜任。命令行工具是一个交互程序,类似你的 shell 或者终端。[Git][2] 和 [Curl][3] 就是两个你也许已经很熟悉的命令行工具。
当你有一小段代码需要在一行中执行多次或者经常性地被执行命令行工具会很实用。Django 开发者执行 `./manage.py runserver` 命令来启动他们的网络服务器Docker 开发者执行 `docker-compose up` 来启动他们的容器。你想要写一个命令行工具的原因可能和你一开始想写代码的原因有很大不同。
对于这个月的 Python 专栏,我们有 3 个库想介绍给希望为自己编写命令行工具的 Python 使用者。
### Click
[Click][4] 是我们最爱的用来开发命令行工具的 Python 包。其:
* 有一个富含例子的出色文档
* 包含说明如何将命令行工具打包成一个更加易于执行的 Python 应用程序
* 自动生成实用的帮助文本
* 使你能够叠加使用可选和必要参数,甚至是 [多个命令][5]
* 有一个 Django 版本( [`django-click`][6] )来编写管理命令
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__':
    hello()
```
`@click.option()` 修饰器声明了一个 [可选参数][7] 并且 `@click.argument()` 修饰器声明了一个 [必要参数][8]。你可以通过叠加修饰器来组合可选和必要参数。`echo()` 方法将结果打印到控制台。
```
$ python hello.py --name='Lacey'
Hello Lacey!
```
### Docopt
[Docopt][9] 是一个命令行工具解析器,类似于命令行工具的 Markdown。如果你喜欢流畅地编写应用文档在本文推荐的库中 Docopt 有着最好的格式化帮助文本。它不是我们最爱的命令行工具开发包的原因是它的文档犹如把人扔进深渊,使你开始使用时会有一些小困难。然而,它仍是一个轻量级广受欢迎的库,特别是当一个漂亮的说明文档对你来说很重要的时候。
Docopt 对于如何格式化文章开头的 docstring 是很特别的。在工具名称后面的 docsring 中顶部元素必须是“Usage:”并且需要列出你希望命令被调用的方式比如自身调用使用参数等等。Usage 需要包含 **help****version** 标记。
docstring 中的第二个元素是“Options:”对于在“Usages:”中提及的可选项和参数,它应当提供更多的信息。你的 docstring 的内容变成了你帮助文本的内容。
```
"""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`
但是如果我带着一个 name 参数调用,`say_hello` 函数就会执行了。
```
$ python hello.py Jeff
Hello Jeff!
```
Docopt 允许同时制定必要和可选参数,且各自有着不同的语法约定。必要参数需要在 `ALLCAPS``<carets>` 中展示,而可选参数需要单双横杠显示,就像‘--like。更多内容可以阅读 Docopt 有关 [patterns][10] 的文档。
### Fire
[Fire][11] 是谷歌的一个命令行工具开发库。尤其令人喜欢的是当你的命令需要更多复杂参数或者处理 Python 对象时,它会聪明地尝试解析你的参数类型。
Fire 的 [文档][12] 包括了海量的样例但是我希望这些文档能被更好地组织。Fire 能够处理 [同一个文件中的多条命令][13]、使用 [对象][14] 的方法作为命令和 [组][15] 命令。
它的弱点在于输出到控制台的文档。命令行中的 docstring 不会出现在帮助文本中,并且帮助文本也不一定标识出参数。
```
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` [打包][16] 命令行工具的使用说明(强烈推荐按照说明操作)。
要打包我们第一个例子中的命令行工具,将以下内容加到你的 `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'` 这种额外的步骤以减少键盘敲击。这些指令也很可能可在我们提到的其他库中使用。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/5/3-python-command-line-tools
作者:[Jeff Triplett][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[hoppipolla-](https://github.com/hoppipolla-)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/laceynwilliams
[1]:https://opensource.com/users/laceynwilliams
[2]:https://git-scm.com/
[3]:https://curl.haxx.se/
[4]:http://click.pocoo.org/5/
[5]:http://click.pocoo.org/5/commands/
[6]:https://github.com/GaretJax/django-click
[7]:http://click.pocoo.org/5/options/
[8]:http://click.pocoo.org/5/arguments/
[9]:http://docopt.org/
[10]:https://github.com/docopt/docopt#usage-pattern-format
[11]:https://github.com/google/python-fire
[12]:https://github.com/google/python-fire/blob/master/docs/guide.md
[13]:https://github.com/google/python-fire/blob/master/docs/guide.md#exposing-multiple-commands
[14]:https://github.com/google/python-fire/blob/master/docs/guide.md#version-3-firefireobject
[15]:https://github.com/google/python-fire/blob/master/docs/guide.md#grouping-commands
[16]:http://click.pocoo.org/5/setuptools/