如何編寫完美的 Python命令行程序?
這個版本有什么新東西嗎?
首先,注意到我給每個參數選項都加了個help參數。由于腳本變得復雜了,help參數可以給腳本的行為添加一些文檔。運行結果如下:> 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. Ifnot provided, a prompt will allow you to type the input text. --output_file FILENAME File in which the encrypted/decrypted text will be written. Ifnot provided, the output text will just be printed. -d, --decrypt / -e, --encrypt Whether you want to encrypt the input textor decrypt it.-k, --keyINTEGER The numeric keyto use for the caesar encryption / decryption. --help Show this message andexit.
兩個新的參數: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 notopen file: wrong_file.txt: No such file or directory
正像help文本中解釋的那樣,如果沒有提供input_file,就使用click.promp讓用戶直接在提示符下輸入文本,在加密模式下這些文本是隱藏的。如下所示:> python caesar_script_v2.py --encrypt --key 2Enter a text: **************yyy.ukectc.eqo
破解密文!
現在設想你是個黑客:你要解密一個用凱撒加密過的密文,但你不知道秘鑰是什么。
最簡單的策略就是用所有可能的秘鑰調用解密函數 25 次,閱讀解密結果,看看哪個是合理的。
但你很聰明,而且也很懶,所以你想讓整個過程自動化。確定解密后的 25 個文本哪個最可能是原始文本的方法之一,就是統計所有這些文本中的英文單詞的個數。這可以使用 PyEnchant 模塊實現:
import clickimport enchantfrom caesar_encryption import encrypt@click.command()@click.option('--input_file', type=click.File('r'),required=True,)@click.option('--output_file', type=click.File('w'),required=True,)defcaesar_breaker(input_file, output_file): cyphertext = input_file.read() english_dictionnary = enchant.Dict("en_US")max_number_of_english_words = 0for key in range(26): plaintext = encrypt(cyphertext, -key) number_of_english_words = 0for word in plaintext.split(' '):if word and english_dictionnary.check(word):number_of_english_words += 1if number_of_english_words > max_number_of_english_words: max_number_of_english_words = number_of_english_words best_plaintext = plaintext best_key = keyclick.echo(f'The most likely encryption key is {best_key}. It gives the following plaintext:\n\n{best_plaintext[:1000]}...')output_file.write(best_plaintext)if __name__ == '__main__':caesar_breaker()
貌似運行得很不錯,但別忘了,好的命令行程序還有個規則需要遵守:
4.A 不是立即完成的任務應當顯示進度條。
示例中的文本包含10^4個單詞,因此該腳本需要大約5秒才能解密。這很正常,因為它需要檢查所有25個秘鑰,每個秘鑰都要檢查10^4個單詞是否出現在英文字典中。
假設你要解密的文本包括10^5個但IC,那么就要花費50秒才能輸出結果,用戶可能會非常著急。
因此我建議這種任務一定要顯示進度條。特別是,顯示進度條還非常容易實現。
下面是個顯示進度條的例子:
import clickimport enchantfrom tqdm import tqdmfrom caesar_encryption import encrypt@click.command()@click.option('--input_file',type=click.File('r'), required=True,)@click.option('--output_file',type=click.File('w'), required=True,)defcaesar_breaker(input_file, output_file): cyphertext = input_file.read() english_dictionnary = enchant.Dict("en_US") best_number_of_english_words = 0for key in tqdm(range(26)): plaintext = encrypt(cyphertext, -key)number_of_english_words = 0for word in plaintext.split(' '):if word and english_dictionnary.check(word): number_of_english_words += 1if number_of_english_words > best_number_of_english_words:best_number_of_english_words = number_of_english_words best_plaintext = plaintext best_key = key click.echo(f'The most likely encryption key is {best_key}. It gives the following plaintext:\n\n{best_plaintext[:1000]}...')output_file.write(best_plaintext)if __name__ == '__main__':caesar_breaker()
你發現區別了嗎?可能不太好找,因為區別真的很小,只有四個字母:tqdm。
tqdm 是 Python 庫的名字,也是它包含的類的名字。只需用它包裹一個可迭代的東西,就能顯示出進度條:
forkeyin tqdm(range(26)):
這樣就能顯示出非常漂亮的進度條。我都不敢相信這是真的。
另外,click也提供類似的顯示進度條的工具(click.progress_bar),但我覺得它的外觀不太容易懂,而且要寫的代碼也多一些。
我希望這篇文章能讓你在改進開發者的體驗上多花點時間。
請輸入評論內容...
請輸入評論/評論長度6~500個字
最新活動更多
- 1 AI狂歡遇上油價破百,全球股市還能漲多久? | 產聯看全球
- 2 OpenAI深夜王炸!ChatGPT Images 2.0實測:中文穩、細節炸,設計師慌了
- 3 6000億美元估值錨定:字節跳動的“去單一化”突圍與估值重構
- 4 Tesla AI5芯片最新進展總結
- 5 連夜測了一波DeepSeek-V4,我發現它可能只剩“審美”這個短板了
- 6 熱點丨AI“瑜亮之爭”:既生OpenClaw,何生Hermes?
- 7 AI界的殺豬盤:9秒刪庫跑路,全員被封號,還繼續扣錢!
- 8 2026,人形機器人只贏了面子
- 9 DeepSeek降價90%:價格屠夫不是身份,是戰略
- 10 AI Infra產業鏈卡在哪里了?


分享













