3 個 Python 命令行工具
有時對於某項工作來說一個命令行工具就足以勝任。命令行工具是一種從你的 shell 或者終端之類的地方交互或運行的程序。Git 和 Curl 就是兩個你也許已經很熟悉的命令行工具。
當你有一小段代碼需要在一行中執行多次或者經常性地被執行,命令行工具就會很有用。Django 開發者執行 ./manage.py runserver
命令來啟動他們的網路伺服器;Docker 開發者執行 docker-compose up
來啟動他們的容器。你想要寫一個命令行工具的原因可能和你一開始想寫代碼的原因有很大不同。
對於這個月的 Python 專欄,我們有 3 個庫想介紹給希望為自己編寫命令行工具的 Python 使用者。
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 對於如何格式化文章開頭的 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 被設計用來返回你的參數鍵值對。如果我不指定上述的 name
調用上面的命令,我會得到一個字典的返回值:
$ 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 的文檔。
Fire
Fire 是谷歌的一個命令行工具開發庫。尤其令人喜歡的是當你的命令需要更多複雜參數或者處理 Python 對象時,它會聰明地嘗試解析你的參數類型。
Fire 的 文檔 包括了海量的樣例,但是我希望這些文檔能被更好地組織。Fire 能夠處理 同一個文件中的多條命令、使用 對象 的方法作為命令和 分組 命令。
它的弱點在於輸出到控制台的文檔。命令行中的 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
打包 命令行工具的使用說明(強烈推薦按照說明操作)。
要打包我們第一個例子中的命令行工具,將以下內容加到你的 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,Lacey Williams Hensche 選題:lujun9972 譯者:hoppipolla- 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive