您好,登錄后才能下訂單哦!
這篇文章主要介紹“如何用Python內置庫創建一個命令行應用程序”,在日常操作中,相信很多人在如何用Python內置庫創建一個命令行應用程序問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何用Python內置庫創建一個命令行應用程序”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
在學習如何使用 argparse 之前,最好知道還有一種方法可以向 Python 腳本傳遞參數。你可以向 Python 腳本傳遞任何參數,并通過使用 sys 模塊訪問這些參數。
為了了解它是如何工作的,創建一個名為 sys_args.py 的文件,并在其中輸入以下代碼:
# sys_args.py import sys def main(): print('You passed the following arguments:') print(sys.argv) if __name__ == '__main__': main()
這段代碼導入sys并打印出sys.argv中的任何內容。argv屬性包含了所有傳遞給腳本的東西的列表,其中第一項是腳本本身。
下面是一個例子,說明當你運行這段代碼和幾個參數的時候會發生什么。
$ python3 sys_args.py --s 45 You passed the following arguments: ['sys_args.py', '--s', '45']
使用sys.argv的問題是,你無法控制可以傳遞給你的應用程序的參數。
不能忽略參數
不能創建默認參數
無法判斷什么是有效參數
這就是為什么使用 argparse 是使用 Python 標準庫的方法。argparse 模塊是非常強大和有用的。讓我們想一想,一個命令行應用程序所遵循的常見過程。
pass:傳入一個文件
do:在你的程序中對該文件做一些處理
output :輸出結果
下面是一個關于如何工作的通用例子。繼續創建file_parser.py并添加以下代碼。
# file_parser.py import argparse def file_parser(input_file, output_file=''): print(f'Processing {input_file}') print('Finished processing') if output_file: print(f'Creating {output_file}') def main(): parser = argparse.ArgumentParser('File parser') parser.add_argument('--infile', help='Input file') parser.add_argument('--out', help='Output file') args = parser.parse_args() if args.infile: file_parser(args.infile, args.out) if __name__ == '__main__': main()
file_parser()函數是進行解析的邏輯所在。在這個例子中,它只接收一個文件名,并將其打印出來。output_file參數的默認值是一個空字符串。
程序的重點在 main()中。在這里你創建了一個 argparse.ArgumentParser()的實例,并給你的解析器起了一個名字。然后你添加兩個參數, --infile和 --out。為了使用這個解析器,你需要調用 parse_args(),它將返回傳遞給你的程序的任何有效參數。最后,你要檢查用戶是否使用了 --infile 標志。如果他們使用了,那么你就運行 file_parser()。
下面是你如何在你的終端中運行代碼。
$ python file_parser.py --infile something.txt Processing something.txt Finished processing
在這里,你用 --infile標志和一個文件名來運行你的腳本。這將運行 main(),然后調用 file_parser()。
下一步是使用你在代碼中聲明的兩個命令行參數嘗試運行你的應用程序。
$ python file_parser.py --infile something.txt --out output.txt Processing something.txt Finished processing Creating output.txt
這一次,你得到了一個額外的輸出行,提到了輸出文件名。這代表你的代碼邏輯中的一個分支。當你指定一個輸出文件時,你可以讓你的代碼通過使用一個新的代碼塊或一個函數來生成該文件。如果你不指定一個輸出文件,那么那個代碼塊就不會運行。
當你使用argparse創建你的命令行工具時,你可以很容易地添加信息,當你的用戶不確定如何正確地與你的程序互動時,可以幫助他們。
現在是時候找出如何從你的應用程序中獲得幫助了
argparse庫將使用你在創建每個參數時提供的信息,自動為你的應用程序創建一個有用的信息。這里是代碼:
# file_parser.py import argparse def file_parser(input_file, output_file=''): print(f'Processing {input_file}') print('Finished processing') if output_file: print(f'Creating {output_file}') def main(): parser = argparse.ArgumentParser('File parser') parser.add_argument('--infile', help='Input file') parser.add_argument('--out', help='Output file') args = parser.parse_args() if args.infile: file_parser(args.infile, args.out) if __name__ == '__main__': main()
現在試著用 -h標志運行這段代碼,你應該看到以下內容。
$ file_parser.py -h usage: File parser [-h] [--infile INFILE] [--out OUT] optional arguments: -h, --help show this help message and exit --infile INFILEInput file --out OUTOutput file
add_argument()的幫助參數被用來創建上面的幫助信息。argparse會自動添加 -h和 -help選項。你可以通過給它一個描述和后記來使你的幫助信息更豐富。
讓我們用它們來改進你的幫助信息。首先,把上面的代碼復制到一個新的文件中,命名為 file_parser_with_description.py,然后把它修改成下面的樣子。
# file_parser_with_description.py import argparse def file_parser(input_file, output_file=''): print(f'Processing {input_file}') print('Finished processing') if output_file: print(f'Creating {output_file}') def main(): parser = argparse.ArgumentParser( 'File parser', description='PyParse - The File Processor', epilog='Thank you for choosing PyParse!', ) parser.add_argument('--infile', help='Input file for conversion') parser.add_argument('--out', help='Converted output file') args = parser.parse_args() if args.infile: file_parser(args.infile, args.out) if __name__ == '__main__': main()
在這里,把description和epilog參數傳遞給ArgumentParser。還更新了 add_argument()的幫助參數,使其更具描述性。
在做了這些修改之后,當你用 -h或 --help運行這個腳本時,你會看到以下輸出。
$ python file_parser_with_description.py -h usage: File parser [-h] [--infile INFILE] [--out OUT] PyParse - The File Processor optional arguments: -h, --help show this help message and exit --infile INFILEInput file for conversion --out OUTConverted output file Thank you for choosing PyParse!
現在可以在你的幫助輸出中看到新的description 和epilog。這給了你的命令行程序一些額外的修飾。
你也可以通過ArgumentParser的 add_help參數在你的應用程序中完全禁用幫助。如果你認為你的幫助文本過于冗長,你可以像這樣禁用它。
# file_parser_no_help.py import argparse def file_parser(input_file, output_file=''): print(f'Processing {input_file}') print('Finished processing') if output_file: print(f'Creating {output_file}') def main(): parser = argparse.ArgumentParser( 'File parser', description='PyParse - The File Processor', epilog='Thank you for choosing PyParse!', add_help=False, ) parser.add_argument('--infile', help='Input file for conversion') parser.add_argument('--out', help='Converted output file') args = parser.parse_args() if args.infile: file_parser(args.infile, args.out) if __name__ == '__main__': main()
通過將 add_help設置為 False,你將禁用 -h和 --help標志。
你可以看到下面的演示。
$ python file_parser_no_help.py --help usage: File parser [--infile INFILE] [--out OUT] File parser: error: unrecognized arguments: --help
在下一節中,你將學習如何為你的參數添加別名!
別名是一個花哨的詞,指的是使用一個替代的標志來做同樣的事情。例如,你知道你可以使用 -h和 --help來訪問程序的幫助信息。-h是 --help的別名,反之亦然。
看看 main()里面的 parser.add_argument()方法有什么變化。
# file_parser_aliases.py import argparse def file_parser(input_file, output_file=''): print(f'Processing {input_file}') print('Finished processing') if output_file: print(f'Creating {output_file}') def main(): parser = argparse.ArgumentParser( 'File parser', description='PyParse - The File Processor', epilog='Thank you for choosing PyParse!', add_help=False, ) parser.add_argument('-i', '--infile', help='Input file for conversion') parser.add_argument('-o', '--out', help='Converted output file') args = parser.parse_args() if args.infile: file_parser(args.infile, args.out) if __name__ == '__main__': main()
這里你改變了第一個 add_argument(),除了接受 -infile之外,還接受了 -i,你還在第二個 add_argument()中加入了 -o。這樣就可以使用兩個新的快捷標志來運行你的代碼。
下面是一個例子。
$ python3 file_parser_aliases.py -i something.txt -o output.txt Processing something.txt Finished processing Creating output.txt
如果你去看argparse文檔,你會發現也可以給子解析器添加別名。子解析器是一種在你的應用程序中創建子命令的方法,這樣它就可以做其他事情。一個很好的例子是Docker,一個虛擬化或容器應用程序。它有一系列的命令,你可以在docker下運行,以及docker compose等等。這些命令中的每一個都有獨立的子命令,你都可以使用。
下面是一個典型的docker命令,用于運行一個容器。
docker exec -it container_name bash
這將用docker啟動一個容器。而如果你要使用docker compose,你將使用一組不同的命令。exec和compose是subparsers的例子。
有時你需要讓你的應用程序接受一些參數,但不接受其他參數。例如,你可能想限制你的應用程序,使它只能創建或刪除文件,而不是同時創建和刪除。
argparse模塊提供了 add_mutually_exclusive_group()方法,它就是這樣做的。
將你的兩個參數添加到一個組對象中,使其相互排斥,如下面的例子。
# file_parser_exclusive.py import argparse def file_parser(input_file, output_file=''): print(f'Processing {input_file}') print('Finished processing') if output_file: print(f'Creating {output_file}') def main(): parser = argparse.ArgumentParser( 'File parser', description='PyParse - The File Processor', epilog='Thank you for choosing PyParse!', add_help=False, ) group = parser.add_mutually_exclusive_group() group.add_argument('-i', '--infile', help='Input file for conversion') group.add_argument('-o', '--out', help='Converted output file') args = parser.parse_args() if args.infile: file_parser(args.infile, args.out) if __name__ == '__main__': main()
首先,你創建了一個相互排斥的組。然后,你把 -i和 -o參數添加到組中,而不是添加到解析器對象中。現在這兩個參數是互斥的。
下面是當你試圖用這兩個參數運行你的代碼時發生的情況。
$ python3 file_parser_exclusive.py -i something.txt -o output.txt usage: File parser [-i INFILE | -o OUT] File parser: error: argument -o/--out: not allowed with argument -i/--infile
用這兩個參數運行你的代碼,會使你的解析器向用戶顯示一條錯誤信息,解釋他們做錯了什么。
在涵蓋了所有這些與使用argparse有關的信息之后,你已經準備好應用你的新技能來創建一個簡單的搜索工具了
在開始創建一個應用程序之前,弄清楚你要完成的任務總是好的。你在本節中想要建立的應用程序應該能夠搜索特定文件類型的文件。為了使它更有趣,你可以添加一個額外的參數,讓你也能選擇性地搜索特定的文件大小。
你可以使用 Python 的 glob 模塊來搜索文件類型。你可以在這里閱讀關于這個模塊的所有信息。
https://docs.python.org/3/library/glob.html
還有一個 fnmatch 模塊,glob 自己也使用它。你現在應該使用 glob,因為它更容易使用,但是如果你有興趣寫一些更專業的東西,那么 fnmatch 可能是你正在尋找的。
然而,由于你希望能夠通過文件大小來選擇性地過濾返回的文件,你可以使用 pathlib,它包括一個類似 glob 的接口。glob 模塊本身并不提供文件大小的信息。
你可以先創建一個名為 pysearch.py 的文件并輸入以下代碼。
# pysearch.py import argparse import pathlib def search_folder(path, extension, file_size=None): """ Search folder for files """ folder = pathlib.Path(path) files = list(folder.rglob(f'*.{extension}')) if not files: print(f'No files found with {extension=}') return if file_size is not None: files = [ f for f in files if f.stat().st_size >= file_size ] print(f'{len(files)} *.{extension} files found:') for file_path in files: print(file_path)
在上面的代碼片段中,首先導入了argparse和pathlib。接下來,創建了search_folder()函數,它接收了三個參數。
path - 要搜索的文件夾
extension - 要尋找的文件擴展名
file_size - 要過濾的文件大小,以字節為單位。
把路徑變成pathlib.Path對象,然后使用其rglob()方法在文件夾中搜索用戶傳入的擴展名。如果沒有找到文件,就向用戶打印一個有意義的信息,然后退出。
如果找到了任何文件,就檢查是否已經設置了filesize。如果它被設置了,就用一個list comprehension來過濾出小于指定的filesize的文件。
接下來,打印出找到的文件的數量,最后在這些文件上循環,打印出它們的名字。
為了使這一切正常工作,需要創建一個命令行界面。你可以通過添加一個包含argparse代碼的main()函數來做到這一點,像這樣。
def main(): parser = argparse.ArgumentParser( 'PySearch', description='PySearch - The Python Powered File Searcher', ) parser.add_argument('-p', '--path', help='The path to search for files', required=True, dest='path') parser.add_argument('-e', '--ext', help='The extension to search for', required=True, dest='extension') parser.add_argument('-s', '--size', help='The file size to filter on in bytes', type=int, dest='size', default=None) args = parser.parse_args() search_folder(args.path, args.extension, args.size) if __name__ == '__main__': main()
這個ArgumentParser()有三個參數,與你傳遞給search_folder()的參數相對應。讓--path和--ext參數成為必需的,而讓--size參數成為可選的。注意,--size參數被設置為type=int,這意味著你不能把它傳成字符串。
add_argument()函數有一個新的參數。它是dest參數,可以用它來告訴你的參數分析器在哪里保存傳遞給它們的參數。
下面是一個腳本運行的例子。
$ python3 pysearch.py -p /Users/michael/Dropbox/python101code/chapter32_argparse -e py -s 650 6 *.py files found: /Users/michael/Dropbox/python101code/chapter32_argparse/file_parser_aliases2.py /Users/michael/Dropbox/python101code/chapter32_argparse/pysearch.py /Users/michael/Dropbox/python101code/chapter32_argparse/file_parser_aliases.py /Users/michael/Dropbox/python101code/chapter32_argparse/file_parser_with_description.py /Users/michael/Dropbox/python101code/chapter32_argparse/file_parser_exclusive.py /Users/michael/Dropbox/python101code/chapter32_argparse/file_parser_no_help.py
現在試試用-s和一個字符串來運行它。
$ python3 pysearch.py -p /Users/michael/Dropbox/python101code/chapter32_argparse -e py -s python usage: PySearch [-h] -p PATH -e EXTENSION [-s SIZE] PySearch: error: argument -s/--size: invalid int value: 'python'
這次我們收到了一個錯誤,因為-s和-size只接受整數。在你自己的機器上運行一下這段代碼,看看當你使用-s和整數時,它是否按你想要的方式工作。
這里有一些想法,你可以用來改進你的代碼版本。
更好地處理擴展文件。現在,它將接受 *.py,這不會像你期望的那樣工作。
更新代碼,以便你可以一次搜索多個擴展名
更新代碼,以便對文件大小的范圍進行過濾(例如,1MB-5MB)。
還有很多其他的功能和改進,你可以添加到這個代碼中,比如添加錯誤處理或單元測試。
到此,關于“如何用Python內置庫創建一個命令行應用程序”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。