如何編寫完美的 Python命令行程序?
這個(gè)版本有什么新東西嗎?
首先,注意到我給每個(gè)參數(shù)選項(xiàng)都加了個(gè)help參數(shù)。由于腳本變得復(fù)雜了,help參數(shù)可以給腳本的行為添加一些文檔。運(yùn)行結(jié)果如下:> python caesar_script_v2.py --h(huán)elpUsage: 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. --h(huán)elp Show this message andexit.
兩個(gè)新的參數(shù):input_file 和 output_file,類型均為 click.File。該庫能夠用正確的模式打開文件,處理可能的錯(cuò)誤,再執(zhí)行函數(shù)。例如:> 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
破解密文!
現(xiàn)在設(shè)想你是個(gè)黑客:你要解密一個(gè)用凱撒加密過的密文,但你不知道秘鑰是什么。
最簡(jiǎn)單的策略就是用所有可能的秘鑰調(diào)用解密函數(shù) 25 次,閱讀解密結(jié)果,看看哪個(gè)是合理的。
但你很聰明,而且也很懶,所以你想讓整個(gè)過程自動(dòng)化。確定解密后的 25 個(gè)文本哪個(gè)最可能是原始文本的方法之一,就是統(tǒng)計(jì)所有這些文本中的英文單詞的個(gè)數(shù)。這可以使用 PyEnchant 模塊實(shí)現(xiàn):
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()
貌似運(yùn)行得很不錯(cuò),但別忘了,好的命令行程序還有個(gè)規(guī)則需要遵守:
4.A 不是立即完成的任務(wù)應(yīng)當(dāng)顯示進(jìn)度條。
示例中的文本包含10^4個(gè)單詞,因此該腳本需要大約5秒才能解密。這很正常,因?yàn)樗枰獧z查所有25個(gè)秘鑰,每個(gè)秘鑰都要檢查10^4個(gè)單詞是否出現(xiàn)在英文字典中。
假設(shè)你要解密的文本包括10^5個(gè)但I(xiàn)C,那么就要花費(fèi)50秒才能輸出結(jié)果,用戶可能會(huì)非常著急。
因此我建議這種任務(wù)一定要顯示進(jìn)度條。特別是,顯示進(jìn)度條還非常容易實(shí)現(xiàn)。
下面是個(gè)顯示進(jìn)度條的例子:
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()
你發(fā)現(xiàn)區(qū)別了嗎?可能不太好找,因?yàn)閰^(qū)別真的很小,只有四個(gè)字母:tqdm。
tqdm 是 Python 庫的名字,也是它包含的類的名字。只需用它包裹一個(gè)可迭代的東西,就能顯示出進(jìn)度條:
forkeyin tqdm(range(26)):
這樣就能顯示出非常漂亮的進(jìn)度條。我都不敢相信這是真的。
另外,click也提供類似的顯示進(jìn)度條的工具(click.progress_bar),但我覺得它的外觀不太容易懂,而且要寫的代碼也多一些。
我希望這篇文章能讓你在改進(jìn)開發(fā)者的體驗(yàn)上多花點(diǎn)時(shí)間。

發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
最新活動(dòng)更多
-
3月27日立即報(bào)名>> 【工程師系列】汽車電子技術(shù)在線大會(huì)
-
4月30日立即下載>> 【村田汽車】汽車E/E架構(gòu)革新中,新智能座艙挑戰(zhàn)的解決方案
-
5月15-17日立即預(yù)約>> 【線下巡回】2025年STM32峰會(huì)
-
即日-5.15立即報(bào)名>>> 【在線會(huì)議】安森美Hyperlux™ ID系列引領(lǐng)iToF技術(shù)革新
-
5月15日立即下載>> 【白皮書】精確和高效地表征3000V/20A功率器件應(yīng)用指南
-
5月16日立即參評(píng) >> 【評(píng)選啟動(dòng)】維科杯·OFweek 2025(第十屆)人工智能行業(yè)年度評(píng)選
推薦專題
- 1 UALink規(guī)范發(fā)布:挑戰(zhàn)英偉達(dá)AI統(tǒng)治的開始
- 2 小米YU7新增835公里續(xù)航版,6-7月面市
- 3 “AI寒武紀(jì)”爆發(fā)至今,五類新物種登上歷史舞臺(tái)
- 4 降薪、加班、裁員三重暴擊,“AI四小龍”已折戟兩家
- 5 昆侖萬維24年?duì)I收56億,AI出海商業(yè)化獲重要進(jìn)展
- 6 光計(jì)算迎來商業(yè)化突破,但落地仍需時(shí)間
- 7 大模型下半場(chǎng):Agent時(shí)代為何更需要開源模型
- 8 中國(guó)“智造”背后的「關(guān)鍵力量」
- 9 優(yōu)必選:營(yíng)收大增主靠小件,虧損繼續(xù)又逢關(guān)稅,能否乘機(jī)器人東風(fēng)翻身?
- 10 營(yíng)收猛增46%,昆侖萬維成為AI“爆品工廠”