애플리케이션을 만들 때 일반적으로 애플리케이션에 작업 방법을 알려줄 수 있기를 원합니다. 이 작업을 수행하는 두 가지 일반적인 방법이 있습니다. 응용 프로그램이 명령줄 인수를 허용하도록 하거나 그래픽 사용자 인터페이스를 만드는 것입니다. 일부 앱은 두 가지를 모두 지원합니다.
명령줄 인터페이스는 서버에서 코드를 실행해야 할 때 유용합니다. 대부분의 서버에는 그래픽 인터페이스가 없습니다. 특히 Linux 서버인 경우 더욱 그렇습니다. 이 경우 GUI를 실행하고 싶어도 실행하지 못할 수도 있습니다.
Python에는 명령줄 인터페이스를 만드는 데 사용할 수 있는 argparse라는 내장 라이브러리가 있습니다. 이 기사에서는 다음 내용을 배우게 됩니다.
argparse 모듈에는 이 기사에서 다룰 수 있는 것보다 훨씬 더 많은 내용이 있습니다. 이에 대해 더 알고 싶다면 설명서를 확인해 보세요.
이제 명령줄에서 매개변수 구문 분석을 시작할 차례입니다.
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 사용의 문제점은 애플리케이션에 전달할 수 있는 인수를 제어할 수 없다는 것입니다.
이것이 Python 표준 라이브러리를 사용하는 방법인 argparse를 사용하는 이유입니다. argparse 모듈은 매우 강력하고 유용합니다. 명령줄 애플리케이션이 따르는 일반적인 프로세스에 대해 생각해 봅시다.
다음은 작동 방식에 대한 일반적인 예입니다. 계속해서 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()
여기서 설명과 에필로그 매개변수를 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()函数,它接收了三个参数。
把路径变成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的窍门,你就可以创建一些非常整洁的应用程序了。
위 내용은 Python 내장 라이브러리를 사용하여 명령줄 애플리케이션 만들기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!