Rumah > Artikel > pembangunan bahagian belakang > Cipta aplikasi baris arahan menggunakan perpustakaan terbina dalam Python
Apabila membuat aplikasi, anda biasanya mahu dapat memberitahu aplikasi anda cara melakukan sesuatu. Terdapat dua cara popular untuk menyelesaikan tugas ini, anda boleh meminta aplikasi menerima hujah baris arahan, atau anda boleh mencipta antara muka pengguna grafik. Sesetengah apl menyokong kedua-duanya.
Antara muka baris arahan berguna apabila anda perlu menjalankan kod anda pada pelayan. Kebanyakan pelayan tidak mempunyai antara muka grafik, terutamanya jika ia adalah pelayan Linux. Dalam kes ini, walaupun anda ingin menjalankan GUI, anda mungkin tidak dapat melakukannya.
Python mempunyai perpustakaan terbina dalam yang dipanggil argparse yang boleh digunakan untuk mencipta antara muka baris arahan. Dalam artikel ini, anda akan mempelajari perkara berikut.
Terdapat lebih banyak lagi modul argparse daripada yang boleh dibincangkan oleh artikel ini. Jika anda ingin mengetahui lebih lanjut mengenainya, anda boleh menyemak dokumentasi.
Kini tiba masanya untuk mula menghuraikan hujah daripada baris arahan.
Sebelum mempelajari cara menggunakan argparse, adalah baik untuk mengetahui bahawa terdapat cara lain untuk menghantar parameter kepada skrip Python. Anda boleh menghantar sebarang parameter kepada skrip Python dan mengakses parameter ini dengan menggunakan modul sys.
Untuk memahami cara ia berfungsi, buat fail bernama sys_args.py dan masukkan kod berikut di dalamnya:
# sys_args.py import sys def main(): print('You passed the following arguments:') print(sys.argv) if __name__ == '__main__': main()
Kod ini mengimport sys dan mencetak apa-apa sahaja dalam argv. Atribut argv mengandungi senarai semua yang dihantar ke skrip, dengan item pertama ialah skrip itu sendiri.
Berikut ialah contoh perkara yang berlaku apabila anda menjalankan kod ini dengan beberapa parameter.
$ python3 sys_args.py --s 45 You passed the following arguments: ['sys_args.py', '--s', '45']
Masalah menggunakan sys.argv ialah anda tidak mempunyai kawalan ke atas hujah yang boleh dihantar kepada aplikasi anda.
Inilah sebabnya menggunakan argparse adalah untuk gunakan kaedah perpustakaan standard Python. Modul argparse sangat berkuasa dan berguna. Mari kita fikirkan tentang proses biasa yang diikuti oleh aplikasi baris arahan.
Berikut ialah contoh generik cara ia berfungsi. Teruskan dan buat file_parser.py dan tambah kod berikut.
# 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()
Fungsi file_parser() ialah logik untuk menghuraikan. Dalam contoh ini, ia hanya mengambil nama fail dan mencetaknya. Nilai lalai parameter output_file ialah rentetan kosong.
Fokus program adalah dalam main(). Di sini anda mencipta contoh argparse.ArgumentParser() dan beri nama penghurai anda. Kemudian anda menambah dua parameter, --infile dan --out. Untuk menggunakan parser ini, anda perlu memanggil parse_args(), yang akan mengembalikan sebarang hujah sah yang dihantar ke program anda. Akhir sekali, anda ingin menyemak sama ada pengguna menggunakan bendera --infile. Jika mereka melakukannya, maka anda menjalankan file_parser().
Begini cara anda menjalankan kod dalam terminal anda.
$ python file_parser.py --infile something.txt Processing something.txt Finished processing
Di sini, anda menjalankan skrip anda dengan bendera --infile dan nama fail. Ini akan menjalankan main() dan kemudian memanggil file_parser().
Langkah seterusnya ialah cuba menjalankan aplikasi anda menggunakan dua argumen baris arahan yang anda nyatakan dalam kod anda.
$ python file_parser.py --infile something.txt --out output.txt Processing something.txt Finished processing Creating output.txt
Kali ini, anda mendapat baris keluaran tambahan yang menyebut nama fail output. Ini mewakili cawangan dalam logik kod anda. Apabila anda menentukan fail output, anda boleh meminta kod anda menjana fail dengan menggunakan blok kod atau fungsi baharu. Jika anda tidak menentukan fail output, blok kod itu tidak akan dijalankan.
Apabila anda menggunakan argparse untuk mencipta alatan baris arahan anda, anda boleh menambah maklumat yang boleh membantu pengguna anda dengan mudah apabila mereka tidak pasti cara berinteraksi dengan program anda dengan betul.
Sekarang tiba masanya untuk mengetahui cara mendapatkan bantuan daripada aplikasi anda
Pustaka argparse akan menggunakan maklumat yang anda berikan semasa mencipta setiap hujah , mencipta secara automatik mesej yang berguna untuk aplikasi anda. Berikut ialah kod:
# 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()
Sekarang cuba jalankan kod ini dengan bendera -h dan anda akan melihat perkara berikut.
$ 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
Parameter bantuan add_argument() digunakan untuk mencipta mesej bantuan di atas. argparse secara automatik menambah pilihan -h dan -help. Anda boleh membuat bantuan anda bermaklumat dengan memberikan penerangan dan catatan tambahan.
Biar kami menggunakannya untuk memperbaik mesej bantuan anda. Mula-mula, salin kod di atas ke dalam fail baharu, namakannya file_parser_with_description.py, dan kemudian ubah suainya supaya kelihatan seperti di bawah.
# 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()
Di sini, hantarkan perihalan dan parameter epilog kepada ArgumentParser. Juga mengemas kini hujah bantuan untuk add_argument() menjadi lebih deskriptif.
Selepas membuat perubahan ini, apabila anda menjalankan skrip ini dengan -h atau --help, anda akan melihat output berikut.
$ 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()函数,它接收了三个参数。
把路径变成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)。
还有很多其他的功能和改进,你可以添加到这个代码中,比如添加错误处理或单元测试。
argparse模块功能齐全,可以用来创建庞大、灵活的命令行应用程序。在本章中,你了解了以下内容。
你可以用argparse模块做更多的事情,不完全包括本章所讲的。请务必查看文档以了解全部细节。现在去试试吧。你会发现,一旦你掌握了使用argparse的窍门,你就可以创建一些非常整洁的应用程序了。
Atas ialah kandungan terperinci Cipta aplikasi baris arahan menggunakan perpustakaan terbina dalam Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!