Vorlage zum Erstellen von Befehlszeilenanwendungen in Python

So erstellen Sie eine Befehlszeilenanwendung in Python

Beim Erstellen einer Befehlszeilenanwendung in Python (z. B. Pythons [httpie]) (https://httpie.org/)) Das Schreiben von ** entry_point ** in setup.py ist der Mainstream, nicht wahr?

setup.py


from setuptools import setup

setup(
    # ...Unterlassung...
    entry_points={
        "console_scripts": [
            "my-console-app=my_console_app.__main__:main"
        ]
    },
    # ...Unterlassung...
)

In dem obigen Fall ist die in __main __. Py "des Pakets" my_console_app "geschriebene" main "-Funktion als eine Anwendung namens" my-console-app "definiert.

Und das Wichtigste ist, wie man diese ** Hauptfunktion ** schreibt. In diesem Artikel möchte ich die Vorlage der Hauptfunktion vorstellen, die sich beim Erstellen von Konsolenanwendungen etabliert hat.

Was in der Hauptfunktion zu schreiben

Alles was Sie für die Hauptfunktion brauchen

Ich denke.

Abrufen von Befehlszeilenargumenten mit argparse

Befehlszeilenanwendungen verwenden normalerweise Argumente. Im Fall von httpie, das im Beispiel erwähnt wird,

$ http PUT http://httpbin.org/put hello=world

Nehmen Sie ein Argument wie dieses. (PUT, http: // httpbin.org / put, hello = world sind alle Argumente) Es gibt eine Standardbibliothek namens ** argparse ** zum Definieren und Abrufen von Befehlszeilenargumenten in Python.

from argparse import ArgumentParser

parser = ArgumentParser(
    prog="my-console-app",
    description="This is my console application.")

parser.add_argument(
    "message",
    action="store",
    help="The message string.")

Definieren Sie folgende Befehlszeilenargumente. Schreiben Sie nicht im Detail über Argparse, da dies den Artikel unnötig lang macht. Bitte überprüfen Sie selbst.

Die Hauptfunktion verwendet den von dieser Argpase erstellten Parser, um Befehlszeilenargumente abzurufen.

__main__.py



from .cli import parser #Cli in der Packung.Definieren Sie den Parser in der py-Datei

def main(argv=sys.argv):
    
    args = parser.parse_args()

Anwendungsinterne Implementierung

Als Nächstes müssen Sie die Anwendung selbst implementieren. Diese Anwendung verwendet die oben erhaltenen Befehlszeilenargumente, um den Ausgabeinhalt zu ändern

__main__.py



from .cli import parser
from .core import program #Kern im Paket.Implementieren Sie die Anwendung in py

def main(argv=sys.argv):

    args = parser.parse_args()
    program(args) #Da Befehlszeilenargumente erforderlich sind, um die Anwendung auszuführen, nehmen Sie args als Argument

Auf diese Weise ist es gut, das Befehlszeilenargument nach dem Parsen als Argument des Programms zu verwenden.

Definition des Kündigungsstatus

Wie lautet der Exit-Status? Der Exit-Status (Englisch: Exit-Status) oder Rückkehrcode (Englisch: Rückkehrcode) eines Prozesses in der Computerprogrammierung ist eine bestimmte Prozedur oder Aufgabe, an die ein untergeordneter Prozess (oder ein angerufener Teilnehmer) delegiert wird. Ist eine kleine Zahl, die an den übergeordneten Prozess (oder Aufrufer) übergeben werden soll, wenn die Ausführung abgeschlossen ist. [End Status-wikipedia](https://ja.wikipedia.org/wiki/%E7%B5%82%E4%BA%86%E3%82%B9%E3%83%86%E3%83%BC% E3% 82% BF% E3% 82% B9)

Erfahren Sie selbst mehr über den Exit-Status. Wenn die Anwendung beendet wird, ist es ** eine Ganzzahl, um zu bestimmen, ob die Anwendung korrekt beendet wurde oder ob sie abnormal mit einem Fehler beendet wurde **. Lassen Sie uns dies in die Hauptfunktion integrieren.

In Bezug auf diesen Endstatus ist es besser, ihn so zu implementieren, dass das Programm in der Anwendung den Endstatus zurückgibt, anstatt ihn in der Hauptfunktion zu definieren. Was bedeutet das?

__main__.py



import sys
from .cli import parser
from .core import program

def main(argv=sys.argv):

    args = parser.parse_args()
    exit_status = program(args) #Es ist gut zu implementieren, damit das Programm in der Anwendung den Endstatus zurückgibt
    
    return sys.exit(exit_status)

Das ist es.

Fehlerausgabe

Da es sich um eine Anwendung handelt, die auf einer Konsole ausgeführt wird, ist es für Benutzer einfacher, Fehler ordnungsgemäß auszugeben.

$ my-console-app -m 1111
Traceback (most recent call last):                                                                                                                            
  File "/home/vagrant/.anyenv/envs/pyenv/versions/2.7.5/lib/python2.7/runpy.py", line 162, in _run_module_as_main                                             
    "__main__", fname, loader, pkg_name)                                                                        
  File "/home/vagrant/.anyenv/envs/pyenv/versions/2.7.5/lib/python2.7/runpy.py", line 72, in _run_code                                                        
    exec code in run_globals                                                                                                                                  
  File "/home/vagrant/lab/Python/my-console-app/my_console_app/__main__.py", line 63, in <module>                                                              
    main()                                                                                                                                                    
  File "/home/vagrant/lab/Python/my-console-app/my_console_app/__main__.py", line 52, in main                                                                   
    exit_code = program(args)                                                                                                                                 
  File "/home/vagrant/lab/Python/my-console-app/my_console_app/__main__.py", line 34, in program                                                               
    print prettyprint(result)                                                                                                                                 
  File "my_console_app/utils.py", line 50, in prettyprint                                                                                                          
    raise TypeError("Message must be string not integer")
TypeError: Message must be string not integer                          

** Der einzige Fehler, den ich übermitteln möchte, ist der letzte Satz **, aber wenn so viele Informationen herauskommen, werden Benutzer, die nichts tun, Angst haben. Daher sollte dieses Fehlerformat nur für den letzten Satz angezeigt werden.

__main__.py



import sys
from .cli import parser
from .core import program

def main(argv=sys.argv):

    args = parser.parse_args()

    try:
        exit_status = program(args) #Es ist gut zu implementieren, damit das Programm in der Anwendung den Endstatus zurückgibt
        return sys.exit(exit_status)

    except Exception as e:
        error_type = type(e).__name__ # 29.6.2 Nachtrag: Hiermit können Sie den Fehlernamen erhalten
        sys.stderr.write("{0}: {1}\n".format(error_type, e.message))
        sys.exit(1) #Wenn der Beendigungsstatus eine andere Ganzzahl als 0 ist, weist dies auf eine abnormale Beendigung hin.

Wenn Sie solchen Code schreiben, wird der Fehler wie folgt ausgegeben.

$ my-console-app -m 1111
TYpeError: Message must be string not integer    

Es ist leichter zu sehen! !!

Wenn Sie jedoch der Meinung sind, dass Sie die Details des Fehlers in der Anwendung nicht sehen können. Es gibt eine Problemumgehung.

  1. Fügen Sie dem von argparse erstellten Parser das Argument ** --stack-trace ** hinzu
  2. Geben Sie den Stack-Trace mithilfe der ** traceback ** -Bibliothek aus, wenn bei Auftreten eines Fehlers das Argument "--stack-trace" vorliegt

cli.py


parser.add_argument(
    "--stack-trace",
    dest="stacktrace",
    action="store_true",
    help="Display the stack trace when error occured.")

__main__.py



import sys
import traceback
from .cli import parser
from .core import program

def main(argv=sys.argv):

    if len(argv) == 1:
        # 2017.04.29 Korrektur
        # len(argv) ==Es war 1 statt 0. Entschuldigung
        parser.parse_args(["-h"])

    args = parser.parse_args(argv)

    try:
        exit_code = program(args)
        sys.exit(exit_code)

    except Exception as e:
        error_type = type(e).__name__ # 29.6.2 Nachtrag: Hiermit können Sie den Fehlernamen erhalten
        stack_trace = traceback.format_exc() #Speichern Sie die Stapelverfolgung, wenn ein Fehler auftritt

        if args.stacktrace: # --stack-Ausgabe-Stack-Trace, wenn ein Trace-Argument vorhanden ist
            print "{:=^30}".format(" STACK TRACE ")
            print stack_trace.strip()

        else:
            sys.stderr.write(
                "{0}: {1}\n".format(e_type, e.message))
            sys.exit(1)

Vorlage zum Erstellen von Befehlszeilenanwendungen in Python

Mit anderen Worten ist die Vorlage der Hauptfunktion wie folgt.

__main__.py



import sys
import traceback
from .cli import parser
from .core import program

def main(argv=sys.argv):

    if len(argv) == 1:
        # 2017.04.29 Korrektur
        # len(argv) ==Es war 1 statt 0. Entschuldigung

        parser.parse_args(["-h"]) #Hilfemeldung ausgeben, wenn keine Befehlszeilenargumente vorhanden sind
        sys.exit(0)

    args = parser.parse_args(argv)

    try:
        exit_code = program(args)
        sys.exit(exit_code)

    except Exception as e:
         error_type = type(e).__name__ # 29.6.2 Nachtrag: Hiermit können Sie den Fehlernamen erhalten
         stack_trace = traceback.format_exc()

        if args.stacktrace:
            print "{:=^30}".format(" STACK TRACE ")
            print stack_trace.strip()

        else:
            sys.stderr.write(
                "{0}: {1}\n".format(e_type, e.message))
            sys.exit(1)

2017.04.29 Korrektur

Vom obigen Code


if len(sys.argv) == 0:
    parser.parse_args(["-h"])

In diesem Teil ist ein Fehler aufgetreten. Korrekt


if len(sys.argv) == 1: # 0 -> 1
    parser.parse_args(["-h"])

Der Zweck dieses Codes (um eine Hilfemeldung vom Parser zu erhalten) besteht darin, dass im Fall von argparse, wenn Sie die Anwendung starten, ohne Befehlszeilenargumente festzulegen,

usage: setup-script [-h] [-l] [--stack-trace] formula project
setup-script: error: too few arguments

Da eine solche Fehlermeldung (was bedeutet, dass kein Argument vorhanden ist) angezeigt wird, ist "parser.parse_args ([" -h "])", wenn "sys.argv" 1 ist, um diesen Fehler nicht auszugeben Die Hilfemeldung wird ausgegeben als.

2017.6.2 Nachtrag

Ich habe gelernt, dass Sie type (e) .__ name__ verwenden können, um den Fehlernamen vom Fehlerobjekt abzurufen.

Recommended Posts

Vorlage zum Erstellen von Befehlszeilenanwendungen in Python
Vorlage zum Schreiben von Batch-Skripten in Python
Zerlegen Sie Befehlsargumente in einer Zeile in Python
So empfangen Sie Befehlszeilenargumente in Python
Meine Gedanken zur Python2.6-Befehlszeilen-App-Vorlage
Persönliche Best Practice zum Einfügen eines Python-Projekts zum Starten einer Befehlszeile in einen Docker-Container
[Für Anfänger] Wie man den Befehl say mit Python benutzt!
Geben Sie in Python einen Unterbefehl als Befehlszeilenargument an
Eine Sammlung von Befehlszeilen, die virtuelle Umgebungen mit Anaconda verwenden
Fizzbuzz in Python (in einer Zeile)
Führen Sie externe Befehle mit Python aus
Techniken zum Sortieren in Python
Versuchen Sie LINE Notify mit Python
Python-Vorlage für Codeforces-manuelle Test-
Externe Befehlsausführung in Python
Über "für _ in range ():" von Python
Ermöglichen Sie die Installation von in Python erstellten Befehlszeilentools
Google sucht mit Python nach der Zeichenfolge in der letzten Zeile der Datei
Überprüfen Sie Python auf Speicherlecks
Befehlszeilenargumentverarbeitung (Python docopt)
Segfo Python in einer Zeile
Suchen Sie mit Python nach externen Befehlen
Drücken Sie einen Befehl in Python (Windows)
Chainer-Befehlszeilentool ChainerCMD
Führen Sie den Shell-Befehl / Python in R aus
Im Python-Befehl zeigt Python auf Python3.8
Empfohlenes Container-Image für Python-Anwendungen
Vorverarbeitungsvorlage für die Datenanalyse (Python)
Führen Sie unittest in Python aus (für Anfänger)
Ich habe Line Benachrichtigung in Python versucht
[Einführung] Fügen Sie Zeilenumbrüche in Python 3 ein
Implementiert in 1 Minute! LINE Benachrichtigen in Python
Befehl für das aktuelle Verzeichnis Python
Python Hinweis: Stellen Sie fest, ob das Befehlszeilenargument in der Liste enthalten ist
So erhalten Sie eine Zeichenfolge aus einem Befehlszeilenargument in Python
CGI Server (1) Python Edition in einer Zeile
[LLDB] Erstellen Sie Ihren eigenen Befehl mit Python
Anmerkung von nfc.ContactlessFrontend () von nfcpy von Python
Inject wird für DDD in Python empfohlen
Gefaltetes Liniendiagramm und Skalierungslinie in Python
Lernen Sie das Entwurfsmuster "Befehl" in Python
Tipps zum Umgang mit Binärdateien in Python
Die Einstellung für die Amateur-Python-Umgebung (für MAC) wird erstellt
Zusammenfassung verschiedener for-Anweisungen in Python
Geben Sie Anmerkungen für Python2 in Stub-Dateien ein!
Lesen Sie die Datei Zeile für Zeile mit Python
Verarbeiten Sie mehrere Listen mit for in Python
Lesen Sie die Datei Zeile für Zeile mit Python
Rufen Sie Optionen in Python sowohl aus JSON-Dateien als auch aus Befehlszeilenargumenten ab
MongoDB mit Python zum ersten Mal
Holen Sie sich ein Zeichen für Conoha mit Python
Beispiel für den Umgang mit EML-Dateien in Python
Tipps zum Erstellen großer Anwendungen mit Flask
AtCoder Spickzettel in Python (für mich)
Ich habe mit Python nach einer Primzahl gesucht
Hinweise zur Verwendung von Python (Pydev) mit Eclipse
Tipps zum Erstellen kleiner Werkzeuge mit Python
[Python] Bool-Wertinversion in einer Zeile
Verwenden Sie pathlib in Maya (Python2.7), um sich auf das kommende Python3.7 vorzubereiten
Hinweise Ich habe nachgeschlagen, um Befehlszeilentools in Python zu erstellen