色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

教你如何編寫完美的Python命令行程序

5RJg_mcuworld ? 來源:lq ? 2019-01-21 14:19 ? 次閱讀

這篇文章將教你如何編寫完美的 Python 命令行程序,提高團隊的生產力,讓大家的工作更舒適。

作者 |Yannick Wolff

作為 Python 開發者,我們經常要編寫命令行程序。比如在我的數據科學項目中,我要從命令行運行腳本來訓練模型,以及計算算法的準確率等。

因此,更方便更易用的腳本能夠很好地提高生產力,特別是在有多個開發者從事同一個項目的場合下。

因此,我建議你遵循以下四條規則:

盡可能提供默認參數

所有錯誤情況必須處理(例如,參數缺失,類型錯誤,找不到文件)

所有參數和選項必須有文檔

不是立即完成的任務應當顯示進度條

舉個簡單的例子

我們把這些規則應用到一個具體的例子上。這個腳本可以使用凱撒加密法加密和解密消息。

假設已經有個寫好的 encrypt 函數(實現如下),我們需要創建一個簡單的腳本,用來加密和解密消息。我們希望讓用戶通過命令行參數選擇加密模式(默認)和解密模式,并選擇一個秘鑰(默認為 1)。

defencrypt(plaintext,key):cyphertext=''forcharacterinplaintext:ifcharacter.isalpha():number=ord(character)number+=keyifcharacter.isupper():ifnumber>ord('Z'):number-=26elifnumberord('z'):number-=26elifnumber

我們的腳本需要做的第一件事就是獲取命令行參數的值。當我搜索“python command line arguments”時,出現的第一個結果是關于sys.argv的,所以我們來試試這個方法……

“初學者”的方法

sys.argv 是個列表,包含用戶在運行腳本時輸入的所有參數(包括腳本名自身)。

例如,如果我輸入:

>pythoncaesar_script.py--key23--decryptmysecretmessagepbvhfuhwphvvdjh

該列表將包含:

['caesar_script.py','--key','23','--decrypt','my','secret','message']

因此只需遍歷該參數列表,找到'--key'(或'-k')以得到秘鑰值,找到'--decrypt'以設置解密模式(實際上只需要使用秘鑰的反轉作為秘鑰即可)。

最后我們的腳本大致如下:

importsysfromcaesar_encryptionimportencryptdefcaesar():key=1is_error=Falseforindex,arginenumerate(sys.argv):ifargin['--key','-k']andlen(sys.argv)>index+1:key=int(sys.argv[index+1])delsys.argv[index]delsys.argv[index]breakforindex,arginenumerate(sys.argv):ifargin['--encrypt','-e']:delsys.argv[index]breakifargin['--decrypt','-d']:key=-keydelsys.argv[index]breakiflen(sys.argv)==1:is_error=Trueelse:forarginsys.argv:ifarg.startswith('-'):is_error=Trueifis_error:print(f'Usage:python{sys.argv[0]}[--key][--encrypt|decrypt]')else:print(encrypt(''.join(sys.argv[1:]),key))if__name__=='__main__':caesar()

這個腳本遵循了一些我們前面推薦的規則:

支持默認秘鑰和默認模式

基本的錯誤處理(沒有提供輸入文本的情況,以及提供了無法識別的參數的情況)

出錯時或者不帶任何參數調用腳本時會顯示文檔:

>pythoncaesar_script_using_sys_argv.pyUsage:pythoncaesar.py[--key][--encrypt|decrypt]

但是,這個凱撒加密法腳本太長了(39 行,其中甚至還沒包括加密代碼本身),而且很難讀懂。

解析命令行參數應該還有更好的辦法……

試試 argparse?

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

我們來看看用 argparse 怎樣編寫凱撒加密的腳本:

importargparsefromcaesar_encryptionimportencryptdefcaesar():parser=argparse.ArgumentParser()group=parser.add_mutually_exclusive_group()group.add_argument('-e','--encrypt',action='store_true')group.add_argument('-d','--decrypt',action='store_true')parser.add_argument('text',nargs='*')parser.add_argument('-k','--key',type=int,default=1)args=parser.parse_args()text_string=''.join(args.text)key=args.keyifargs.decrypt:key=-keycyphertext=encrypt(text_string,key)print(cyphertext)if__name__=='__main__':caesar()

這段代碼也遵循了上述規則,而且與前面的手工編寫的腳本相比,可以提供更準確的文檔,以及更具有交互性的錯誤處理:

>pythoncaesar_script_using_argparse.py--encodeMymessageusage:caesar_script_using_argparse.py[-h][-e|-d][-kKEY][text[text...]]caesar_script_using_argparse.py:error:unrecognizedarguments:--encode>pythoncaesar_script_using_argparse.py--helpusage:caesar_script_using_argparse.py[-h][-e|-d][-kKEY][text[text...]]positionalarguments:textoptionalarguments:-h,--helpshowthishelpmessageandexit-e,--encrypt-d,--decrypt-kKEY,--keyKEY

但是,仔細看了這段代碼后,我發現(雖然有點主觀)函數開頭的幾行(從7行到13行)定義了參數,但定義方式并不太優雅:它太臃腫了,而且完全是程式化的。應該有更描述性、更簡潔的方法。

click 能做得更好!

幸運的是,有個 Python 庫能提供與 argparse 同樣的功能(甚至還能提供更多),它的代碼風格更優雅。這個庫的名字叫 click。

這里是凱撒加密腳本的第三版,使用了 click:

importclickfromcaesar_encryptionimportencrypt@click.command()@click.argument('text',nargs=-1)@click.option('--decrypt/--encrypt','-d/-e')@click.option('--key','-k',default=1)defcaesar(text,decrypt,key):text_string=''.join(text)ifdecrypt:key=-keycyphertext=encrypt(text_string,key)click.echo(cyphertext)if__name__=='__main__':caesar()

注意現在參數和選項都在修飾器里定義,定義好的參數直接作為函數參數提供。

我來解釋一下上面代碼中的一些地方:

腳本參數定義中的nargs參數指定了該參數期待的單詞的數目(一個用引號括起來的字符串算一個單詞)。默認值是1。這里nargs=-1允許接收任意數目的單詞。

--encrypt/--decrypt這種寫法可以定義完全互斥的選項(類似于argparse中的add_mutually_exclusive_group函數),它將產生一個布爾型參數。

click.echo是該庫提供的一個工具函數,它的功能與print相同,但兼容Python 2和Python 3,還有一些其他功能(如處理顏色等)。

添加一些隱秘性

這個腳本的參數(被加密的消息)應當是最高機密。而我們卻要求用戶直接在終端里輸入文本,使得這些文本被記錄在命令歷史中,這不是很諷刺嗎?

解決方法之一就是使用隱藏的提示?;蛘呖梢詮妮斎胛募凶x取文本,對于較長的文本來說更實際一些?;蛘呖梢愿纱嘧層脩暨x擇。

輸出也一樣:用戶可以保存到文件中,也可以輸出到終端。這樣就得到了凱撒腳本的最后一個版本:

importclickfromcaesar_encryptionimportencrypt@click.command()@click.option('--input_file',type=click.File('r'),help='Fileinwhichthereisthetextyouwanttoencrypt/decrypt.''Ifnotprovided,apromptwillallowyoutotypetheinputtext.',)@click.option('--output_file',type=click.File('w'),help='Fileinwhichtheencrypted/decryptedtextwillbewritten.''Ifnotprovided,theoutputtextwilljustbeprinted.',)@click.option('--decrypt/--encrypt','-d/-e',help='Whetheryouwanttoencrypttheinputtextordecryptit.')@click.option('--key','-k',default=1,help='Thenumerickeytouseforthecaesarencryption/decryption.')defcaesar(input_file,output_file,decrypt,key):ifinput_file:text=input_file.read()else:text=click.prompt('Enteratext',hide_input=notdecrypt)ifdecrypt:key=-keycyphertext=encrypt(text,key)ifoutput_file:output_file.write(cyphertext)else:click.echo(cyphertext)if__name__=='__main__':caesar()

這個版本有什么新東西嗎?

首先,注意到我給每個參數選項都加了個help參數。由于腳本變得復雜了,help參數可以給腳本的行為添加一些文檔。運行結果如下:

>pythoncaesar_script_v2.py--helpUsage:caesar_script_v2.py[OPTIONS]Options:--input_fileFILENAMEFileinwhichthereisthetextyouwanttoencrypt/decrypt.Ifnotprovided,apromptwillallowyoutotypetheinputtext.--output_fileFILENAMEFileinwhichtheencrypted/decryptedtextwillbewritten.Ifnotprovided,theoutputtextwilljustbeprinted.-d,--decrypt/-e,--encryptWhetheryouwanttoencrypttheinputtextordecryptit.-k,--keyINTEGERThenumerickeytouseforthecaesarencryption/decryption.--helpShowthismessageandexit.

兩個新的參數:input_file 和 output_file,類型均為 click.File。該庫能夠用正確的模式打開文件,處理可能的錯誤,再執行函數。例如:

>pythoncaesar_script_v2.py--decrypt--input_filewrong_file.txtUsage:caesar_script_v2.py[OPTIONS]Error:Invalidvaluefor"--input_file":Couldnotopenfile:wrong_file.txt:Nosuchfileordirectory

正像help文本中解釋的那樣,如果沒有提供input_file,就使用click.promp讓用戶直接在提示符下輸入文本,在加密模式下這些文本是隱藏的。如下所示:

>pythoncaesar_script_v2.py--encrypt--key2Enteratext:**************yyy.ukectc.eqo

破解密文!

現在設想你是個黑客:你要解密一個用凱撒加密過的密文,但你不知道秘鑰是什么。

最簡單的策略就是用所有可能的秘鑰調用解密函數 25 次,閱讀解密結果,看看哪個是合理的。

但你很聰明,而且也很懶,所以你想讓整個過程自動化。確定解密后的 25 個文本哪個最可能是原始文本的方法之一,就是統計所有這些文本中的英文單詞的個數。這可以使用 PyEnchant 模塊實現:

importclickimportenchantfromcaesar_encryptionimportencrypt@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=0forkeyinrange(26):plaintext=encrypt(cyphertext,-key)number_of_english_words=0forwordinplaintext.split(''):ifwordandenglish_dictionnary.check(word):number_of_english_words+=1ifnumber_of_english_words>max_number_of_english_words:max_number_of_english_words=number_of_english_wordsbest_plaintext=plaintextbest_key=keyclick.echo(f'Themostlikelyencryptionkeyis{best_key}.Itgivesthefollowingplaintext: {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秒才能輸出結果,用戶可能會非常著急。

因此我建議這種任務一定要顯示進度條。特別是,顯示進度條還非常容易實現。

下面是個顯示進度條的例子:

importclickimportenchantfromtqdmimporttqdmfromcaesar_encryptionimportencrypt@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=0forkeyintqdm(range(26)):plaintext=encrypt(cyphertext,-key)number_of_english_words=0forwordinplaintext.split(''):ifwordandenglish_dictionnary.check(word):number_of_english_words+=1ifnumber_of_english_words>best_number_of_english_words:best_number_of_english_words=number_of_english_wordsbest_plaintext=plaintextbest_key=keyclick.echo(f'Themostlikelyencryptionkeyis{best_key}.Itgivesthefollowingplaintext: {best_plaintext[:1000]}...')output_file.write(best_plaintext)if__name__=='__main__':caesar_breaker()

你發現區別了嗎?可能不太好找,因為區別真的很小,只有四個字母:tqdm。

tqdm 是 Python 庫的名字,也是它包含的類的名字。只需用它包裹一個可迭代的東西,就能顯示出進度條:

forkeyintqdm(range(26)):

這樣就能顯示出非常漂亮的進度條。我都不敢相信這是真的。

另外,click也提供類似的顯示進度條的工具(click.progress_bar),但我覺得它的外觀不太容易懂,而且要寫的代碼也多一些。

我希望這篇文章能讓你在改進開發者的體驗上多花點時間。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 函數
    +關注

    關注

    3

    文章

    4338

    瀏覽量

    62739
  • python
    +關注

    關注

    56

    文章

    4799

    瀏覽量

    84810
  • 數據科學
    +關注

    關注

    0

    文章

    165

    瀏覽量

    10078

原文標題:如何編寫完美的 Python 命令行程序?

文章出處:【微信號:mcuworld,微信公眾號:嵌入式資訊精選】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    用于分析可執行程序和內存轉儲的命令行工具介紹

    Axf Tool 是桃芯科技一個用于分析可執行程序和內存轉儲的命令行工具。該工具已集成到 ingWizard 的項目快捷菜單里。
    的頭像 發表于 11-03 17:00 ?1291次閱讀
    用于分析可執<b class='flag-5'>行程序</b>和內存轉儲的<b class='flag-5'>命令行</b>工具介紹

    cmd網絡經典命令行

    cmd網絡經典命令行:
    發表于 06-11 15:17 ?36次下載
    cmd網絡經典<b class='flag-5'>命令行</b>

    caxa命令行中的應用

    caxa命令行中的應用 命令行對于大多用戶來說往往只是輸入數據的作用,但是其中的奧妙還有很多,下面就給大家
    發表于 10-18 18:18 ?2305次閱讀

    博達環網配置命令行

    博達工業交換要環網配置命令行
    發表于 12-27 16:24 ?0次下載

    CMD的命令行高級教程

    CMD的命令行高級教程
    發表于 10-24 08:31 ?30次下載
    CMD的<b class='flag-5'>命令行</b>高級教程

    Linux命令行與shell腳本編寫

    Linux命令行與shell腳本編寫
    發表于 01-11 16:50 ?4次下載

    命令行中記筆記的神器-Jrnl

    Jrnl 是用Python編寫命令行筆記應用程序,用起來非常簡單方便,特別適合需要快速記錄文本信息的同學。
    的頭像 發表于 02-24 14:07 ?1465次閱讀
    在<b class='flag-5'>命令行</b>中記筆記的神器-Jrnl

    如何在Linux命令行中運行Python腳本

    Python 是一種高級編程語言,被廣泛應用于數據科學、機器學習、Web 開發等領域。在 Linux 操作系統中,Python 是一個默認安裝的解釋器,用戶可以通過命令行界面(CLI)來運行
    的頭像 發表于 05-12 14:49 ?1699次閱讀

    Fcoder從命令行批量轉換為TIFF

    命令行批量轉換為TIFF 2TIFF圖像轉換軟件是一個專業的命令行實用程序,用于以批處理模式將辦公文檔和圖像轉換為TIFF?;诤唵蔚?b class='flag-5'>命令行語法,它可以在PC、服務器上使用,也可以內
    的頭像 發表于 05-22 14:13 ?820次閱讀
    Fcoder從<b class='flag-5'>命令行</b>批量轉換為TIFF

    linux命令行與shell編程實戰

    Linux命令行與Shell編程實戰主要涉及以下內容: Linux命令行基礎:學習Linux命令行的基本操作,如文件管理、進程管理、網絡配置等。熟悉使用命令行能夠提高工作效率,提升自己
    的頭像 發表于 11-08 10:57 ?794次閱讀

    linux切換到命令行模式

    在Linux中,可以通過以下步驟切換到命令行模式: 打開終端??梢栽趹貌藛沃姓业浇K端或命令行終端。 在終端中輸入命令“exit”或“logout”,然后按回車鍵。 系統會提示您輸入管理員密碼。輸入
    的頭像 發表于 11-13 16:47 ?1803次閱讀

    linux命令行運行步驟

    運行Linux命令行涉及以下步驟: 打開終端 在Linux系統中,打開命令行界面的方式有多種,最常見的是打開終端應用程序??梢栽趹?b class='flag-5'>程序菜單中找到終端,點擊打開。 熟悉
    的頭像 發表于 11-17 10:18 ?811次閱讀

    pycharm命令行終端運行代碼

    Python是一種非常流行的編程語言,許多開發者使用它來編寫各種應用程序和腳本。為了方便開發者編寫和測試代碼,PyCharm是一種集成開發環境(IDE),它提供了許多功能和工具,其中包
    的頭像 發表于 11-22 11:20 ?4964次閱讀

    eclipse怎么使用命令行

    。JDK是運行Java程序所必需的環境,而Eclipse則是一個基于Java開發的IDE。在確保安裝完畢后,我們可以通過以下步驟來在命令行
    的頭像 發表于 12-06 11:26 ?2728次閱讀

    idea如何輸入命令行參數

    在許多軟件開發和系統管理的任務中,我們經常需要向應用程序傳遞命令行參數。命令行參數是在運行時傳遞給程序的值,用于指定程序的行為和配置選項。本
    的頭像 發表于 12-06 15:01 ?1186次閱讀
    主站蜘蛛池模板: 羞羞影院午夜男女爽爽免费| WWW国产精品人妻一二三区| 朝鲜女人性猛交| 日本熟妇乱妇熟色在线电影| 国产精品久久久久久搜索| 亚洲成人三级| 久久久99精品成人片中文| 91久久偷偷做嫩草影院免| 日本边添边摸边做边爱边| 国产午夜电影在线观看不卡| 中文字幕 人妻熟女| 日本高清免费一本在线观看 | 毛片免费观看的视频在线| wwww69| 亚洲AV无码乱码国产麻豆穿越| 久久免费精彩视频| 成人无码国产AV免费看 | 中文字幕一区二区三区在线观看| 嫩B人妻精品一区二区三区| 高清无码中文字幕在线观看视频| 亚洲精品一区二区在线看片| 暖暖免费观看日本在线视频| 国产伦子沙发午休系列资源曝光 | 人人舔人人爱| 精品国产中文字幕在线视频| fryee性欧美18 19| 亚洲欧美日本中文子不卡| 日本19禁啪啪吃奶大尺度| 久久国产精品久久国产精品| 大桥未久与黑人中出视频| 伊人22222| 偷窥美女3| 女人张开腿让男人添| 好妞操| 国产MD视频一区二区三区| 4k岛国精品午夜高清在线观看| 忘忧草研究所 麻豆| 欧美日本高清动作片www网站| 精品久久伊人| 国产伦精品一区二区三区免费| bl(高h)文|