通過範例學習如何優化Python命令行界面(中) — 好文分享

林品融
Taiwan Code School
Published in
5 min readJan 15, 2019

{翻譯至:https://blog.sicara.com/perfect-python-command-line-interfaces-7d5d4efad6a2}

來談談argparse套件

argparse是用於解析命令行參數的Python標準庫模塊。

讓我們看看我們的凱撒腳本如何使用argparse:

這將尊重我們的規範,並提供比上述手工腳本更精確的文檔和更具交互性的錯誤處理:

> python caesar_script_using_argparse.py --encode My message

usage: caesar_script_using_argparse.py [-h] [-e | -d] [-k KEY] [text [text ...]]
caesar_script_using_argparse.py: error: unrecognized arguments: --encode
> python caesar_script_using_argparse.py --help

usage: caesar_script_using_argparse.py [-h] [-e | -d] [-k KEY] [text [text ...]]
positional arguments:
text
optional arguments:
-h, --help show this help message and exit
-e, --encrypt
-d, --decrypt
-k KEY, --key KEY

然而,關於代碼,原作者發現 — 這有點主觀 — 原作者的函數的第一行(從第7行到第13行),其中參數被定義,不是很優雅:它太冗長和程序化,而它 可以以更緊湊和聲明的方式完成。

利用click套件來優化!

我們很幸運:有一個Python套件提供與argparse(和更多)相同的功能,具有更漂亮的代碼樣式:它的名稱是click。

這是我們的凱薩腳本的第三個版本,使用click套件:

值得注意的是,在參數和選項上限定了他本身的類型,這使得它們可以作為我們函數的參數直接調用。

讓我們分析一下以上代碼中的一些細微之處:

● script參數的nargs參數指定了此參數所需的連續單詞的數量(“帶有這樣的帶引號的字符串”計為1個單詞)。 默認值為1.這裡,nargs = -1允許提供任意數量的單詞。

● 符號 — encrypt / — decrypt允許定義互斥選項(與argparse中的add_mutually_exclusive_group函數一樣),這將產生Boolean 參數。

● click.echo是一個由套件提供的小實用程序,它與打印相同,但與Python 2和3兼容,並具有一些額外的功能(顏色處理等)。

增加一些保密性

我們的腳本參數應該是將被加密的絕密消息。 要求使用者直接在他的電腦輸入他的純文本,卻會在命令歷史中保留非常的諷刺大家不這麼覺得嗎?

以更安全的方式執行此操作的解決方案是使用隱藏提示。 或者我們可以從輸入文件中讀取文本,這對於長文本來說更加實用。 或者也可以讓用戶選擇!

讓我們對輸出做同樣的事情:用戶可以將其保存到文件中,或者在電腦中顯示。 這導致我們對凱撒腳本的最後一個改進版本:

這個版本有什麼更新?

首先,請注意我為每個參數或選項添加了一個幫助參數。 由於腳本變得有點複雜,它允許向文檔添加有關其行為的一些細節,現在看起來像這樣:

> python caesar_script_v2.py --helpUsage: caesar_script_v2.py [OPTIONS]Options:--input_file FILENAME          File in which there is the text you want to encrypt/decrypt. If not provided, a prompt will allow you to type the input text.--output_file FILENAME         File in which the encrypted/decrypted text will be written. If not provided, the output text will just be printed.-d, --decrypt / -e, --encrypt  Whether you want to encrypt the input text or decrypt it.-k, --key INTEGER              The numeric key to use for the caesar encryption / decryption.--help                         Show this message and exit.

我們有兩個新的參數,input_file和output_file,類型為click.File。 在進入函數之前,庫設法以正確的模式打開文件並處理可能發生的錯誤。 例如:

> python caesar_script_v2.py --decrypt --input_file wrong_file.txtUsage: caesar_script_v2.py [OPTIONS]Error: Invalid value for "--input_file": Could not open file: wrong_file.txt: No such file or directory

如幫助文本中所述,如果未提供input_file,我們使用click.prompt允許用戶直接在提示中鍵入其文本,該提示將在加密模式下隱藏。 這將是這樣的:

> python caesar_script_v2.py --encrypt --key 2Enter a text: **************yyy.ukectc.eqo

--

--