Heim  >  Artikel  >  Backend-Entwicklung  >  Erstellen Sie eine Befehlszeilenanwendung mit integrierten Python-Bibliotheken

Erstellen Sie eine Befehlszeilenanwendung mit integrierten Python-Bibliotheken

PHPz
PHPznach vorne
2023-04-16 22:31:01824Durchsuche

Erstellen Sie eine Befehlszeilenanwendung mit integrierten Python-Bibliotheken

Wenn Sie eine Anwendung erstellen, möchten Sie Ihrer Anwendung normalerweise sagen können, wie sie etwas tun soll. Es gibt zwei gängige Möglichkeiten, diese Aufgabe zu erfüllen: Sie können die Anwendung Befehlszeilenargumente akzeptieren lassen oder Sie können eine grafische Benutzeroberfläche erstellen. Einige Apps unterstützen beides.

Die Befehlszeilenschnittstelle ist hilfreich, wenn Sie Ihren Code auf dem Server ausführen müssen. Die meisten Server verfügen nicht über eine grafische Oberfläche, insbesondere wenn es sich um Linux-Server handelt. In diesem Fall ist es möglicherweise nicht möglich, die GUI auszuführen, selbst wenn Sie sie ausführen möchten.

Python verfügt über eine integrierte Bibliothek namens argparse, die zum Erstellen einer Befehlszeilenschnittstelle verwendet werden kann. In diesem Artikel erfahren Sie Folgendes.

  • Argumente analysieren
  • Nützliche Informationen erstellen
  • Aliase hinzufügen
  • Sich gegenseitig ausschließende Argumente verwenden
  • Ein einfaches Suchtool erstellen

Das argparse-Modul bietet viel mehr, als in diesem Artikel behandelt werden kann. Wenn Sie mehr darüber erfahren möchten, können Sie sich die Dokumentation ansehen.

Jetzt ist es an der Zeit, mit dem Parsen der Parameter über die Befehlszeile zu beginnen.

Parsing von Argumenten

Bevor Sie lernen, wie man argparse verwendet, sollten Sie wissen, dass es eine andere Möglichkeit gibt, Parameter an ein Python-Skript zu übergeben. Sie können beliebige Parameter an ein Python-Skript übergeben und mithilfe des sys-Moduls auf diese Parameter zugreifen.

Um zu verstehen, wie es funktioniert, erstellen Sie eine Datei mit dem Namen sys_args.py und geben Sie darin den folgenden Code ein:

# sys_args.py
 import sys
 def main():
 print('You passed the following arguments:')
 print(sys.argv)
 if __name__ == '__main__':
 main()

Dieser Code importiert sys und druckt alles aus, was in sys.argv enthalten ist. Das argv-Attribut enthält eine Liste aller an das Skript übergebenen Elemente, wobei das erste Element das Skript selbst ist.

Hier ist ein Beispiel dafür, was passiert, wenn Sie diesen Code mit ein paar Parametern ausführen.

$ python3 sys_args.py --s 45
 You passed the following arguments:
 ['sys_args.py', '--s', '45']

Das Problem bei der Verwendung von sys.argv besteht darin, dass Sie keine Kontrolle über die Argumente haben, die an Ihre Anwendung übergeben werden können.

  • Parameter können nicht ignoriert werden.
  • Standardparameter können nicht erstellt werden. Das argparse-Modul ist sehr leistungsstark und nützlich. Denken wir über einen allgemeinen Prozess nach, dem eine Befehlszeilenanwendung folgt.
  • pass: Übergeben Sie eine Datei.

do: Bearbeiten Sie die Datei in Ihrem Programm.

    output: Geben Sie das Ergebnis aus.
  • Hier ist ein allgemeines Beispiel dafür, wie es funktioniert. Erstellen Sie file_parser.py und fügen Sie den folgenden Code hinzu.
  • # 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()
  • Die Funktion file_parser() ist die Logik für das Parsen. In diesem Beispiel wird lediglich ein Dateiname verwendet und ausgedruckt. Der Standardwert des Parameters „output_file“ ist eine leere Zeichenfolge.
Der Schwerpunkt des Programms liegt in main(). Hier erstellen Sie eine Instanz von argparse.ArgumentParser() und geben Ihrem Parser einen Namen. Dann fügen Sie zwei Parameter hinzu, --infile und --out. Um diesen Parser verwenden zu können, müssen Sie parse_args() aufrufen, das alle gültigen Argumente zurückgibt, die an Ihr Programm übergeben wurden. Abschließend möchten Sie überprüfen, ob der Benutzer das Flag --infile verwendet hat. Wenn dies der Fall ist, führen Sie file_parser() aus.

So führen Sie den Code in Ihrem Terminal aus.

$ python file_parser.py --infile something.txt
 Processing something.txt
 Finished processing

Hier führen Sie Ihr Skript mit dem Flag --infile und einem Dateinamen aus. Dadurch wird main() ausgeführt und dann file_parser() aufgerufen.

Der nächste Schritt besteht darin, zu versuchen, Ihre Anwendung mit den beiden Befehlszeilenargumenten auszuführen, die Sie in Ihrem Code deklariert haben.

$ python file_parser.py --infile something.txt --out output.txt
 Processing something.txt
 Finished processing
 Creating output.txt

Dieses Mal erhalten Sie eine zusätzliche Ausgabezeile, in der der Name der Ausgabedatei aufgeführt ist. Dies stellt einen Zweig in der Logik Ihres Codes dar. Wenn Sie eine Ausgabedatei angeben, können Sie Ihren Code veranlassen, die Datei mithilfe eines neuen Codeblocks oder einer Funktion zu generieren. Wenn Sie keine Ausgabedatei angeben, wird dieser Codeblock nicht ausgeführt.

Wenn Sie argparse zum Erstellen Ihrer Befehlszeilentools verwenden, können Sie ganz einfach Informationen hinzufügen, die Ihren Benutzern helfen können, wenn sie sich nicht sicher sind, wie sie richtig mit Ihrem Programm interagieren sollen.

Jetzt ist es an der Zeit, herauszufinden, wie Sie Hilfe von Ihrer Anwendung erhalten.

Erstellen Sie eine Hilfenachricht.

Die argparse-Bibliothek erstellt automatisch eine nützliche Nachricht für Ihre Anwendung, indem sie die Informationen verwendet, die Sie beim Erstellen jedes Arguments angeben. Hier ist der Code:

# 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()

Versuchen Sie nun, diesen Code mit der Flagge -h auszuführen, und Sie sollten Folgendes sehen. Der Hilfeparameter von

$ 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() wird verwendet, um die obige Hilfemeldung zu erstellen. argparse fügt automatisch die Optionen -h und -help hinzu. Sie können Ihre Hilfe informativ gestalten, indem Sie ihr eine Beschreibung und ein Nachwort hinzufügen.

Lassen Sie uns sie nutzen, um Ihre Hilfemeldungen zu verbessern. Kopieren Sie zunächst den obigen Code in eine neue Datei, nennen Sie sie file_parser_with_description.py und ändern Sie sie dann so, dass sie wie folgt aussieht.

# 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()

Übergeben Sie hier die Beschreibungs- und Epilog-Parameter an ArgumentParser. Außerdem wurde das Hilfeargument für add_argument() aktualisiert, um es aussagekräftiger zu machen.

Nachdem Sie diese Änderungen vorgenommen haben und dieses Skript mit -h oder --help ausführen, wird die folgende Ausgabe angezeigt.

$ 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)。

还有很多其他的功能和改进,你可以添加到这个代码中,比如添加错误处理或单元测试。

总结

argparse模块功能齐全,可以用来创建庞大、灵活的命令行应用程序。在本章中,你了解了以下内容。

  • 解析参数
  • 创建有用的信息
  • 添加别名
  • 使用相互排斥的参数
  • 创建一个简单的搜索工具

你可以用argparse模块做更多的事情,不完全包括本章所讲的。请务必查看文档以了解全部细节。现在去试试吧。你会发现,一旦你掌握了使用argparse的窍门,你就可以创建一些非常整洁的应用程序了。

Das obige ist der detaillierte Inhalt vonErstellen Sie eine Befehlszeilenanwendung mit integrierten Python-Bibliotheken. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:51cto.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen