Dieser Artikel ist der 18. Tag des Python-Adventskalenders.
In letzter Zeit habe ich die Befehlszeile etwas häufiger verwendet. Ich habe die Standardeinstellung argparse verwendet, bin mir aber nicht sicher, daher suche ich nach anderen Optionen und vergleiche sie. Ich werde untersuchen und mit click, fire vergleichen, was sehr beliebt zu sein scheint Ich werde.
Dieser Artikel verwendet die folgenden Versionen der Bibliothek:
pipenv --python 3.7.5
$ pipenv install click==7.0
$ pipenv install fire==0.2.1
python commands.py [command] [options] NAME
$ python commands.py hello World
Hello, World
$ python commands.py hellow World
Goodbye, World
$ python commands.py hello --greeting=Wazzup World
Whazzup, World
$ python commands.py goodbye --greeting=Later World
Later, World
$ python commands.py hello --caps World
HELLO, WORLD
$ python commands.py hello --greeting=Wazzup --caps World
WAZZUP, WORLD
In diesem Artikel werden die Methoden jeder Bibliothek verglichen, um die folgenden Funktionen entlang des Ablaufs des Referenzartikels zu implementieren.
Zusätzliche Funktionen (werden später geschrieben)
Ich werde das grundlegende Schreiben verschiedener Bibliotheken machen.
Argparse
import argparse
def main():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
hello_parser = subparsers.add_parser("hello")
goodbye_parser = subparsers.add_parser("goodbye")
parser.parse_args()
if __name__ == "__main__":
main()
Sie haben jetzt zwei Befehle und eine integrierte Hilfemeldung. Die Hilfemeldung ändert sich, wenn sie als Option für den Befehl Hallo ausgeführt wird.
$ python argparse/commands.py --helop
usage: commands.py [-h] {hello} ...
positional arguments:
{hello}
optional arguments:
-h, --help show this help message and exit
$ python commands.py hello --help
usage: commands.py hello [-h]
optional arguments:
-h, --help show this help message and exit
Click
import click
@click.group()
def greet():
pass
@greet.command()
def hello(**kwargs):
pass
@greet.command()
def goodbye(**kwargs):
pass
if __name__ == "__main__":
greet()
Sie haben jetzt zwei Befehle und eine integrierte Hilfemeldung. Die Hilfemeldung ändert sich, wenn sie als Option für den Befehl Hallo ausgeführt wird.
$ python click/commands.py --help
Usage: commands.py [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
goodbye
hello
$ python click/commands.py hello --help
Usage: commands.py hello [OPTIONS]
Options:
--help Show this message and exit.
Fire
import fire
def hello():
pass
def goodbye():
pass
if __name__ == "__main__":
fire.Fire({"hello": hello, "goodbye": goodbye})
Sie haben jetzt zwei Befehle und eine integrierte Hilfemeldung. Die Hilfemeldung ändert sich, wenn sie als Option für den Befehl Hallo ausgeführt wird. Darüber hinaus bietet Fire Hilfe im Man-Format. Feuer kann auch auf folgende Arten implementiert werden.
import fire
def hello():
pass
def goodbye():
pass
if __name__ == "__main__":
fire.Fire()
import fire
class Greet:
def hello(self):
pass
def goodbye(self):
pass
if __name__ == "__main__":
greet = Greet()
fire.Fire(greet)
$ python fire/commands.py --help
NAME
commands.py
SYNOPSIS
commands.py COMMAND
COMMANDS
COMMAND is one of the following:
goodbye
hello
$ python fire/commands.py hello --help
NAME
commands.py hello
SYNOPSIS
commands.py hello
Es ist sehr interessant mit einem anderen Ansatz für jede Bibliothek in der Basis. Als nächstes fügen wir das NAME-Argument und die Logik hinzu, um das Ergebnis von jedem Tool auszugeben.
Hier fügen wir dem oben geschriebenen Code eine neue Logik hinzu. Fügen Sie der neuen Zeile einen Kommentar hinzu, um Ihren Zweck anzugeben. Das Argument (Positionsspezifikation) ist eine erforderliche Eingabe. Dieses Mal fügen wir ein Argument mit "Name" hinzu, damit das Tool eine bestimmte Person begrüßen kann.
Argparse
Verwenden Sie add_argument
, um einem Unterbefehl ein Argument hinzuzufügen. Setzen Sie es dann mit set_defautls
, um die Funktion auszuführen. Führen Sie schließlich nach dem Parsen der Argumente die Funktion mit args.func (args)
aus.
import argparse
def hello(args):
print(f"Hello, {args.name}")
def goodbye(args):
print(f"Goodbye, {args.name}")
def main():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
hello_parser = subparsers.add_parser("hello")
hello_parser.add_argument("name")
hello_parser.set_defaults(func=hello)
goodbye_parser = subparsers.add_parser("goodbye")
goodbye_parser.add_argument("name")
goodbye_parser.set_defaults(func=goodbye)
args = parser.parse_args()
args.func(args)
if __name__ == "__main__":
main()
$ python argparse/commands.py hello World
Hello, World
$ python argparse/commands.py hello --help
usage: commands.py hello [-h] name
positional arguments:
name
optional arguments:
-h, --help show this help message and
Click
Verwenden Sie "@ click.argument", um Click ein Argument hinzuzufügen. In diesem Fall übergeben Sie nur den Argumentnamen, es gibt jedoch verschiedene Optionen.
$ python click/commands.py hello World
Hello, World
$ python click/commands.py hello --help
Usage: commands.py hello [OPTIONS] NAME
Options:
--help Show this message and exit.
Fire
Fire fügt der Funktion nur Argumente hinzu. In Fire ist es im Grunde nur eine Funktions- / Klassenimplementierung, also ziemlich einfach.
import fire
def hello(name):
print(f"Hello, {name}")
def goodbye(name):
print(f"Goodbye, {name}")
if __name__ == "__main__":
fire.Fire({"hello": hello, "goodbye": goodbye})
$ python fire/commands.py hello World
Hello, World
(test-cli) ikura4@ikura1-ThinkPad:~/test/test-cli$ python fire/commands.py hello --help
NAME
commands.py hello
SYNOPSIS
commands.py hello NAME
POSITIONAL ARGUMENTS
NAME
NOTES
You can also use flags syntax for POSITIONAL ARGUMENTS
(END)
Hier fügen wir die neue Logik erneut zu dem Code hinzu, den wir oben geschrieben haben. Die Option ist eine nicht wesentliche Eingabe, die angegeben werden kann. Fügen Sie in diesem Beispiel "--greeting = [greeting]" und "--caps" hinzu. Der Standardwert für "Begrüßung" ist "Hallo" oder "Auf Wiedersehen", und der Benutzer kann einen beliebigen Wert übergeben. Wenn Sie beispielsweise "--greeting = Wazzup" setzen, wird "Wazzup, [Name]" angezeigt. Wenn "--caps" angegeben ist, ist die Anzeige alles. Zum Beispiel zeigt "--caps" "HALLO [NAME]" an.
Argparse
import argparse
#Da fing ich an, Grüße zu übermitteln
#Vereinheitlicht, um die Funktion zu begrüßen
def greet(args):
output = f"{args.greeting}, {args.name}"
if args.caps:
output = output.upper()
print(output)
def main():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
hello_parser = subparsers.add_parser("hello")
#Fügen Sie dem Argument einen Namen hinzu
hello_parser.add_argument("name")
#Begrüßungsoption und Standard hinzugefügt
hello_parser.add_argument("--greeting", default="Hello")
#Flag mit der Standardeinstellung False hinzufügen
hello_parser.add_argument("--caps", action="store_true")
hello_parser.set_defaults(func=greet)
goodbye_parser = subparsers.add_parser("goodbye")
goodbye_parser.add_argument("name")
goodbye_parser.add_argument("--greeting", default="Goodbye")
goodbye_parser.add_argument("--caps", action="store_true")
goodbye_parser.set_defaults(func=greet)
args = parser.parse_args()
args.func(args)
if __name__ == "__main__":
main()
$ python argparse/commands.py hello --greeting=Wazzup World
Wazzup, World
$ python argparse/commands.py hello --caps World
HELLO, WORLD
$ python argparse/commands.py hello --greeting=Wazzup --caps World
WAZZUP, WORLD
$ python argparse/commands.py hello --help
usage: commands.py hello \[-h\] [--greeting GREETING] [--caps] name
positional arguments:
name
optional arguments:
-h, --help show this help message and exit
--greeting GREETING
--caps
Click
Fügen Sie "Begrüßung" und "Großbuchstaben" mit "@ click.option" hinzu. Da es einen Standardwert gibt, habe ich eine Funktion erstellt.
import click
def greeter(name, greeting, caps):
output = f"{greeting}, {name}"
if caps:
output = output.upper()
print(output)
@click.group()
def greet():
pass
@greet.command()
@click.argument("name")
#Begrüßungsoption und Standard hinzugefügt
@click.option("--greeting", default="Hello")
#Flag hinzugefügt(is_flag=Kann mit True gekennzeichnet werden)
@click.option("--caps", is_flag=True)
def hello(name, greeting, caps):
greeter(name, greeting, caps)
@greet.command()
@click.argument("name")
@click.option("--greeting", default="Goodbye")
@click.option("--caps", is_flag=True)
def goodbye(name, greeting, caps):
greeter(name, greeting, caps)
if __name__ == "__main__":
greet()
$ python click/commands.py hello --greeting=Wazzup World
Wazzup, World
$ python click/commands.py hello --caps World
HELLO, WORLD
$ python click/commands.py hello --greeting=Wazzup --caps World
WAZZUP, WORLD
$ python click/commands.py hello --helpUsage: commands.py hello [OPTIONS] NAME
Options:
--greeting TEXT
--caps
--help Show this message and exit.
Fire
Fügen Sie "Begrüßung" und "Großbuchstaben" hinzu, indem Sie der Funktion Argumente hinzufügen. Da es eine gemeinsame Verarbeitung gibt, habe ich sie auch noch einmal in "grüßen" zusammengefasst.
import fire
def greet(name, greeting, caps):
output = f"{greeting}, {name}"
if caps:
output = output.upper()
print(output)
def hello(name, greeting="Hello", caps=False):
greet(name, greeting, caps)
def goodbye(name, greeting="Goodbye", caps=False):
greet(name, greeting, caps)
if __name__ == "__main__":
fire.Fire({"hello": hello, "goodbye": goodbye})
Es gibt eine Einschränkung mit Feuer, wenn Sie an einem Bool vorbeikommen. Das Token nach dem Übergeben von "--caps" wird an --caps übergeben. Es gibt drei Möglichkeiten, dies anzugeben:
$ python fire/commands.py hello World --caps
$ python fire/commands.py hello --caps True World
$ python fire/commands.py hello --caps=True World
$ python fire/commands.py hello --greeting=Wazzup World
Wazzup, World
$ python fire/commands.py hello --caps=True World
HELLO, WORLD
$ python fire/commands.py hello --greeting=Wazzup --caps=True World
WAZZUP, WORLD
$ python fire/commands.py hello --help
NAME
commands.py hello
SYNOPSIS
commands.py hello NAME <flags>
POSITIONAL ARGUMENTS
NAME
FLAGS
--greeting=GREETING
--caps=CAPS
NOTES
You can also use flags syntax for POSITIONAL ARGUMENTS
(END)
Argparser
――Es hat den Reiz, eine Standardbibliothek zu sein, und es ist gut, andererseits verwendet zu werden, aber ich habe den Eindruck, dass es nicht zum Erstellen einer einfachen CLI geeignet ist.Click
――Ich mag Dekorateure, weil der Code klein und so organisiert ist, dass er einfache Dinge erledigt, aber wenn ich mir den Code von "schwarz" usw. ansehe, gibt es zu viele Dekorateure und die Lesbarkeit ist eingeschränkt, also in kleinem Maßstab Ich habe den Eindruck, dass es geeignet ist.Die meisten Dinge, die ich mache, sind im Grunde genommen klein, also werde ich Feuer benutzen. Ich denke an Click next.
Comparing Python Command-Line Parsing Libraries – Argparse, Docopt, and Click
Recommended Posts