久久精品国产亚洲高清|精品日韩中文乱码在线|亚洲va中文字幕无码久|伊人久久综合狼伊人久久|亚洲不卡av不卡一区二区|精品久久久久久久蜜臀AV|国产精品19久久久久久不卡|国产男女猛烈视频在线观看麻豆

    1. <style id="76ofp"></style>

      <style id="76ofp"></style>
      <rt id="76ofp"></rt>
      <form id="76ofp"><optgroup id="76ofp"></optgroup></form>
      1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

        手機(jī)站
        千鋒教育

        千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

        千鋒教育

        掃一掃進(jìn)入千鋒手機(jī)站

        領(lǐng)取全套視頻
        千鋒教育

        關(guān)注千鋒學(xué)習(xí)站小程序
        隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

        當(dāng)前位置:首頁(yè)  >  技術(shù)干貨  > 如何編寫(xiě)完美的Python命令行程序?

        如何編寫(xiě)完美的Python命令行程序?

        來(lái)源:千鋒教育
        發(fā)布人:qyf
        時(shí)間: 2023-02-23 16:48:00 1677142080

        如何編寫(xiě)完美的Python命令行程序

          這篇文章將教你如何編寫(xiě)完美的 Python 命令行程序,提高團(tuán)隊(duì)的生產(chǎn)力,讓大家的工作更舒適。

          作為 Python 開(kāi)發(fā)者,我們經(jīng)常要編寫(xiě)命令行程序。比如在我的數(shù)據(jù)科學(xué)項(xiàng)目中,我要從命令行運(yùn)行腳本來(lái)訓(xùn)練模型,以及計(jì)算算法的準(zhǔn)確率等。

          因此,更方便更易用的腳本能夠很好地提高生產(chǎn)力,特別是在有多個(gè)開(kāi)發(fā)者從事同一個(gè)項(xiàng)目的場(chǎng)合下。

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

          盡可能提供默認(rèn)參數(shù)值

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

          所有參數(shù)和選項(xiàng)必須有文檔

          不是立即完成的任務(wù)應(yīng)當(dāng)顯示進(jìn)度條

          舉個(gè)簡(jiǎn)單的例子

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

          假設(shè)已經(jīng)有個(gè)寫(xiě)好的 encrypt 函數(shù)(實(shí)現(xiàn)如下),我們需要?jiǎng)?chuàng)建一個(gè)簡(jiǎn)單的腳本,用來(lái)加密和解密消息。我們希望讓用戶通過(guò)命令行參數(shù)選擇加密模式(默認(rèn))和解密模式,并選擇一個(gè)秘鑰(默認(rèn)為 1)。

          def encrypt(plaintext, key):

          cyphertext = ''

          for character in plaintext:

          if character.isalpha():

          number = ord(character)

          number += key

          if character.isupper():

          if number > ord('Z'):

          number -= 26

          elif number < ord('A'):

          number += 26

          elif character.islower():

          if number > ord('z'):

          number -= 26

          elif number < ord('a'):

          number += 26

          character = chr(number)

          cyphertext += character

          return cyphertext

          我們的腳本需要做的第一件事就是獲取命令行參數(shù)的值。當(dāng)我搜索“python command line arguments”時(shí),出現(xiàn)的第一個(gè)結(jié)果是關(guān)于sys.argv的,所以我們來(lái)試試這個(gè)方法……

          “初學(xué)者”的方法

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

          例如,如果我輸入:

          > python caesar_script.py --key 23 --decrypt my secret message

          pb vhfuhw phvvdjh

          該列表將包含:

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

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

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

          import sys

          from caesar_encryption import encrypt

          def caesar():

          key = 1

          is_error = False

          for index, arg in enumerate(sys.argv):

          if arg in ['--key', '-k'] and len(sys.argv) > index + 1:

          key = int(sys.argv[index + 1])

          del sys.argv[index]

          del sys.argv[index]

          break

          for index, arg in enumerate(sys.argv):

          if arg in ['--encrypt', '-e']:

          del sys.argv[index]

          break

          if arg in ['--decrypt', '-d']:

          key = -key

          del sys.argv[index]

          break

          if len(sys.argv) == 1:

          is_error = True

          else:

          for arg in sys.argv:

          if arg.startswith('-'):

          is_error = True

          if is_error:

          print(f'Usage: python {sys.argv[0]} [ --key] [ --encrypt|decrypt ]')

          else:

          print(encrypt(' '.join(sys.argv[1:]), key))

          if __name__ == '__main__':

          caesar()

          這個(gè)腳本遵循了一些我們前面推薦的規(guī)則:

          支持默認(rèn)秘鑰和默認(rèn)模式

          基本的錯(cuò)誤處理(沒(méi)有提供輸入文本的情況,以及提供了無(wú)法識(shí)別的參數(shù)的情況)

          出錯(cuò)時(shí)或者不帶任何參數(shù)調(diào)用腳本時(shí)會(huì)顯示文檔:

          > python caesar_script_using_sys_argv.py

          Usage: python caesar.py [ --key] [ --encrypt|decrypt ]

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

          解析命令行參數(shù)應(yīng)該還有更好的辦法……

          試試 argparse?

          argparse 是 Python 用來(lái)解析命令行參數(shù)的標(biāo)準(zhǔn)庫(kù)。

          我們來(lái)看看用 argparse 怎樣編寫(xiě)凱撒加密的腳本:

          import argparse

          from caesar_encryption import encrypt

          def caesar():

          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.key

          if args.decrypt:

          key = -key

          cyphertext = encrypt(text_string, key)

          print(cyphertext)

          if __name__ == '__main__':

          caesar()

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

          > 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

          但是,仔細(xì)看了這段代碼后,我發(fā)現(xiàn)(雖然有點(diǎn)主觀)函數(shù)開(kāi)頭的幾行(從7行到13行)定義了參數(shù),但定義方式并不太優(yōu)雅:它太臃腫了,而且完全是程式化的。應(yīng)該有更描述性、更簡(jiǎn)潔的方法。

          click 能做得更好!

          幸運(yùn)的是,有個(gè) Python 庫(kù)能提供與 argparse 同樣的功能(甚至還能提供更多),它的代碼風(fēng)格更優(yōu)雅。這個(gè)庫(kù)的名字叫 click。

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

          import click

          from caesar_encryption import encrypt

          @click.command()

          @click.argument('text', nargs=-1)

          @click.option('--decrypt/--encrypt', '-d/-e')

          @click.option('--key', '-k', default=1)

          def caesar(text, decrypt, key):

          text_string = ' '.join(text)

          if decrypt:

          key = -key

          cyphertext = encrypt(text_string, key)

          click.echo(cyphertext)

          if __name__ == '__main__':

          caesar()

          注意現(xiàn)在參數(shù)和選項(xiàng)都在修飾器里定義,定義好的參數(shù)直接作為函數(shù)參數(shù)提供。

          我來(lái)解釋一下上面代碼中的一些地方:

          ●腳本參數(shù)定義中的nargs參數(shù)指定了該參數(shù)期待的單詞的數(shù)目(一個(gè)用引號(hào)括起來(lái)的字符串算一個(gè)單詞)。默認(rèn)值是1。這里nargs=-1允許接收任意數(shù)目的單詞。

          ●--encrypt/--decrypt這種寫(xiě)法可以定義完全互斥的選項(xiàng)(類似于argparse中的add_mutually_exclusive_group函數(shù)),它將產(chǎn)生一個(gè)布爾型參數(shù)。

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

          添加一些隱秘性

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

          解決方法之一就是使用隱藏的提示?;蛘呖梢詮妮斎胛募凶x取文本,對(duì)于較長(zhǎng)的文本來(lái)說(shuō)更實(shí)際一些。或者可以干脆讓用戶選擇。

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

          import click

          from caesar_encryption import encrypt

          @click.command()

          @click.option(

          '--input_file',

          type=click.File('r'),

          help='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.',

          )

          @click.option(

          '--output_file',

          type=click.File('w'),

          help='File in which the encrypted / decrypted text will be written.'

          'If not provided, the output text will just be printed.',

          )

          @click.option(

          '--decrypt/--encrypt',

          '-d/-e',

          help='Whether you want to encrypt the input text or decrypt it.'

          )

          @click.option(

          '--key',

          '-k',

          default=1,

          help='The numeric key to use for the caesar encryption / decryption.'

          )

          def caesar(input_file, output_file, decrypt, key):

          if input_file:

          text = input_file.read()

          else:

          text = click.prompt('Enter a text', hide_input=not decrypt)

          if decrypt:

          key = -key

          cyphertext = encrypt(text, key)

          if output_file:

          output_file.write(cyphertext)

          else:

          click.echo(cyphertext)

          if __name__ == '__main__':

          caesar()

          這個(gè)版本有什么新東西嗎?

          首先,注意到我給每個(gè)參數(shù)選項(xiàng)都加了個(gè)help參數(shù)。由于腳本變得復(fù)雜了,help參數(shù)可以給腳本的行為添加一些文檔。運(yùn)行結(jié)果如下:

          > python caesar_script_v2.py --help

          Usage: 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.

          兩個(gè)新的參數(shù):input_file 和 output_file,類型均為 click.File。該庫(kù)能夠用正確的模式打開(kāi)文件,處理可能的錯(cuò)誤,再執(zhí)行函數(shù)。例如:

          > python caesar_script_v2.py --decrypt --input_file wrong_file.txt

          Usage: caesar_script_v2.py [OPTIONS]

          Error: Invalid value for "--input_file": Could not open file: wrong_file.txt: No such file or directory

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

          > python caesar_script_v2.py --encrypt --key 2

          Enter a text: **************

          yyy.ukectc.eqo

        tags:
        聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
        10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
        請(qǐng)您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
        免費(fèi)領(lǐng)取
        今日已有369人領(lǐng)取成功
        劉同學(xué) 138****2860 剛剛成功領(lǐng)取
        王同學(xué) 131****2015 剛剛成功領(lǐng)取
        張同學(xué) 133****4652 剛剛成功領(lǐng)取
        李同學(xué) 135****8607 剛剛成功領(lǐng)取
        楊同學(xué) 132****5667 剛剛成功領(lǐng)取
        岳同學(xué) 134****6652 剛剛成功領(lǐng)取
        梁同學(xué) 157****2950 剛剛成功領(lǐng)取
        劉同學(xué) 189****1015 剛剛成功領(lǐng)取
        張同學(xué) 155****4678 剛剛成功領(lǐng)取
        鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
        董同學(xué) 138****2867 剛剛成功領(lǐng)取
        周同學(xué) 136****3602 剛剛成功領(lǐng)取
        相關(guān)推薦HOT
        python字符串截取?

        在Python中,字符串是一種非常常見(jiàn)的數(shù)據(jù)類型,它可以用來(lái)表示文本、數(shù)字、符號(hào)等內(nèi)容。在實(shí)際應(yīng)用中,我們經(jīng)常需要對(duì)字符串進(jìn)行截取,以便獲取...詳情>>

        2023-11-02 17:56:27
        Python socket C/S結(jié)構(gòu)的聊天室應(yīng)用實(shí)現(xiàn)?

        隨著互聯(lián)網(wǎng)的發(fā)展,聊天室應(yīng)用成為人們?nèi)粘I钪惺殖R?jiàn)的一種社交方式。Python語(yǔ)言的Socket模塊是實(shí)現(xiàn)網(wǎng)絡(luò)通信的重要工具,可以輕松地實(shí)現(xiàn)C/...詳情>>

        2023-11-02 17:53:38
        用while求1到100的奇數(shù)和?

        在計(jì)算機(jī)編程中,循環(huán)語(yǔ)句是非常重要的一部分。而while語(yǔ)句是其中最基本也是最常用的一種。它的作用是在滿足一定條件的情況下,重復(fù)執(zhí)行一段代...詳情>>

        2023-11-02 17:50:57
        python創(chuàng)建一個(gè)集合?

        在Python中,集合是一種無(wú)序且不重復(fù)的數(shù)據(jù)類型,可以用于存儲(chǔ)一組元素。創(chuàng)建一個(gè)集合非常簡(jiǎn)單,只需要使用大括號(hào){}或者set()函數(shù)即可。使用大...詳情>>

        2023-11-02 17:34:02
        linux改文件屬主命令?

        Linux文件相關(guān)命令1、命令一:cat cat命令應(yīng)該是在Linux中查看文件內(nèi)容最常見(jiàn)的命令了。使用cat命令會(huì)打印指定文件的所有內(nèi)容到標(biāo)準(zhǔn)輸出上,比...詳情>>

        2023-10-31 19:58:15
        天全县| 龙岩市| 滦平县| 江达县| 东丽区| 福海县| 晋州市| 怀集县| 霍林郭勒市| 涞源县| 宁都县| 隆尧县| 湘乡市| 建昌县| 怀安县| 阿荣旗| 华蓥市| 化德县| 临高县| 简阳市| 肥城市| 察隅县| 江西省| 荃湾区| 招远市| 美姑县| 长宁区| 九龙坡区| 浑源县| 海林市| 巴里| 崇义县| 夹江县| 绥芬河市| 宿迁市| 奇台县| 崇礼县| 翁牛特旗| 珠海市| 江门市| 鄂托克前旗|