作者:HelloGitHub-Prodesire
HelloGitHub 的《講解開源項目》系列,項目地址:https://github.com/HelloGitHub-Team/Article
一、前言
在本系列前面四篇文章中,我們介紹了 argparse
的方方面面。它無疑是強大的,但使用方式上略顯麻煩。需要先設置解析器,再定義參數,再解析命令行,最后實現業務邏輯。
而今天要介紹的 docopt 則是站在一個全新的視角來審視命令行。你可曾想過,一個命令行程序的幫助信息其實已然包含了這個命令行的完整元信息,那么是否可以通過定義幫助信息來定義命令行呢?docopt
就是基於這樣的想法去設計的。
本系列文章默認使用 Python 3 作為解釋器進行講解。
若你仍在使用 Python 2,請注意兩者之間語法和庫的使用差異哦~
二、介紹
docopt 基於長久以來在幫助信息和手冊中描述程序接口的約定,其接口描述是形式化的幫助信息。它能夠根據命令行程序中定義的接口描述,來自動生成解析器。
三、快速開始
3.1 定義接口描述/幫助信息
第一步要做的就是命令行程序的定義接口描述或者是幫助信息,這樣 docopt
就能知道命令行的元信息,從而自動解析。
接口描述通常定義在一個模塊的文檔字符串中,我們仍然以在 Python 命令行之旅:初探 argparse
的例子為例,講解如何使用 docopt
來定義接口描述。
在 cmd.py
中,我們定義如下接口描述:
"""Num accumulator.
Usage:
cmd.py [--sum] <num>...
cmd.py (-h | --help)
Options:
-h --help Show help.
--sum Sum the nums (default: find the max).
"""
在上面的接口描述中,我們定義了命令行程序 cmd.py
接受一個或多個數字 num
,而 --sum
選項則是可選,-h
或 --help
則輸出幫助信息。
若提供 --sum
,則累加給定的數字;反之,取給定多個數字中最大的一個。這個業務邏輯我們將在后文實現。
3.2 解析命令行
定義好接口描述后,就可以使用 docopt
進行解析,寫法非常簡單:
from docopt import docopt
arguments = docopt(__doc__, options_first=True)
print(arguments)
由於我們之前是將接口描述定義在模塊的文檔字符串中,那么直接使用 __doc__
即可獲得接口描述。然后使用 docopt
函數即可解析命令行為參數字典。為了支持負數,我們將 options_first
設置為 True
。
當我們執行 python3 cmd.py --sum 1 2 3
時,將會得到如下內容:
{'--help': False,
'--sum': True,
'<num>': ['1', '2', '3']}
可以看到:
- 沒有提供
-h
或者--help
,所以arguments
中--help
為False
- 提供了
--sum
,所以arguments
中--sum
為True
- 提供了
<num>...
為1 2 3
,所以arguments
中<num>
為['1', '2', '3']
3.3 業務邏輯
獲得了解析后的命令行參數,我們就可以根據自己的業務需求做進一步處理了。
在本文示例中,我們希望當用戶提供 --sum
選項時,是對給定的一組數字求和;反之則是取最大值,那么就可以這么寫:
nums = (int(num) for num in arguments['<num>'])
if arguments['--sum']:
result = sum(nums)
else:
result = max(nums)
print(result) # 基於上文的 python3 cmd.py --sum 1 2 3 參數,其結果為 6
3.4 代碼梳理
使用 docopt
的方式非常簡單,我們將上文的代碼匯總下,以有一個更清晰的認識:
# cmd.py
# 1. 定義接口描述
"""Num accumulator.
Usage:
cmd.py [--sum] <num>...
cmd.py (-h | --help)
Options:
-h --help Show help.
--sum Sum the nums (default: find the max).
"""
from docopt import docopt
# 2. 解析命令行
arguments = docopt(__doc__, options_first=True)
# 3. 業務邏輯
nums = (int(num) for num in arguments['<num>'])
if arguments['--sum']:
result = sum(nums)
else:
result = max(nums)
print(result)
若我們需要對一組數字求和,只需執行:
$ python3 cmd.py --sum 1 0 -1
0
若我們需要對一組數字求最大值,只需執行:
$ python3 cmd.py 1 0 -1
1
我們還可以通過 -h
或 --help
參數查看使用說明和幫助,也就是我們定義的接口描述。
四、小節
docopt
的思路非常簡單,就是定義接口描述,然后幫你解析命令行為參數字典,接下來就根據這個字典來編寫業務邏輯。
重點就是在於如何定義接口描述,在下一篇文章中,我們來深入了解下如何定義命令、選項、位置參數等接口描述。
『講解開源項目系列』——讓對開源項目感興趣的人不再畏懼、讓開源項目的發起者不再孤單。跟着我們的文章,你會發現編程的樂趣、使用和發現參與開源項目如此簡單。歡迎留言聯系我們、加入我們,讓更多人愛上開源、貢獻開源~