Lors de la création d'une application de ligne de commande en Python (telle que python httpie
)
Écrire ** entry_point ** dans setup.py
est le courant dominant, n'est-ce pas?
setup.py
from setuptools import setup
setup(
# ...Omission...
entry_points={
"console_scripts": [
"my-console-app=my_console_app.__main__:main"
]
},
# ...Omission...
)
Dans le cas ci-dessus, la fonction main
écrite en __main __. Py
du package my_console_app
est définie comme une application appelée my-console-app
.
Et l'important est de savoir comment écrire cette ** fonction principale **. Dans cet article, je vais vous présenter le modèle de la fonction principale qui s'est établie lors de la création d'applications console.
Tout ce dont vous avez besoin pour la fonction principale
Je pense.
Les applications de ligne de commande acceptent généralement des arguments. Par exemple, dans le cas de httpie mentionné dans l'exemple,
$ http PUT http://httpbin.org/put hello=world
Prenez un argument comme celui-ci. (PUT
, http: // httpbin.org / put
, hello = world
sont tous des arguments)
Il existe une bibliothèque standard appelée ** argparse ** pour définir et obtenir des arguments de ligne de commande en 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.")
Définissez des arguments de ligne de commande comme celui-ci. N'écrivez pas sur argparse en détail car cela rendra l'article inutilement long. Veuillez vérifier par vous-même.
La fonction main utilise l'analyseur créé par cette argpase pour obtenir des arguments de ligne de commande.
__main__.py
from .cli import parser #Cli à l'intérieur du paquet.Définir l'analyseur dans le fichier py
def main(argv=sys.argv):
args = parser.parse_args()
Ensuite, vous devez implémenter l'application elle-même. Cette application utilise les arguments de ligne de commande obtenus ci-dessus pour modifier le contenu de sortie, donc
__main__.py
from .cli import parser
from .core import program #Noyau à l'intérieur du paquet.Implémenter l'application dans py
def main(argv=sys.argv):
args = parser.parse_args()
program(args) #Étant donné que les arguments de ligne de commande sont nécessaires pour exécuter l'application, prenez args comme argument
De cette façon, il est bon de prendre l'argument de ligne de commande après l'analyse comme argument du programme.
Quel est l'état de sortie? L'état de sortie (anglais: état de sortie) ou code retour (anglais: code retour) d'un processus en programmation informatique est une procédure ou une tâche spécifique à laquelle un processus enfant (ou appelé) est délégué. Est un petit nombre à transmettre au processus parent (ou à l'appelant) une fois l'exécution terminée. [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)
En savoir plus sur le statut de sortie vous-même. Quoi qu'il en soit, lorsque l'application se ferme, c'est ** un entier pour déterminer si l'application s'est terminée correctement ou si elle s'est terminée anormalement avec une erreur **. Incorporons cela dans la fonction principale.
Concernant cet état de fin, il est préférable de l'implémenter pour que le programme à l'intérieur de l'application renvoie l'état de fin plutôt que de le définir dans la fonction principale. Qu'est-ce que ça veut dire?
__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) #Il est bon de mettre en œuvre pour que le programme à l'intérieur de l'application renvoie l'état de fin
return sys.exit(exit_status)
Voilà ce que c'est.
Puisqu'il s'agit d'une application qui s'exécute sur une console, il est plus facile pour les utilisateurs de générer correctement les erreurs.
$ 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
** La seule erreur que je veux signaler est la dernière phrase **, mais quand autant d'informations sortent, les utilisateurs qui ne font rien auront peur. Par conséquent, ce format d'erreur doit être affiché uniquement pour la dernière phrase.
__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) #Il est bon de mettre en œuvre pour que le programme à l'intérieur de l'application renvoie l'état de fin
return sys.exit(exit_status)
except Exception as e:
error_type = type(e).__name__ # 29.6.2 Addendum: vous pouvez obtenir le nom de l'erreur avec ce
sys.stderr.write("{0}: {1}\n".format(error_type, e.message))
sys.exit(1) #Si l'état de fin est un entier différent de 0, cela indique une fin anormale.
Si vous écrivez un code comme celui-ci, l'erreur sera générée comme suit.
$ my-console-app -m 1111
TYpeError: Message must be string not integer
C'est plus facile à voir! !!
Mais si vous pensez que vous ne pouvez pas voir les détails de l'erreur dans l'application. Il existe une solution de contournement.
--stack-trace
lorsqu'une erreur se produitcli.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 Correction
# len(argv) ==C'était 1 au lieu de 0. Excusez-moi
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 Addendum: vous pouvez obtenir le nom de l'erreur avec ce
stack_trace = traceback.format_exc() #Enregistrer la trace de la pile lorsqu'une erreur se produit
if args.stacktrace: # --stack-Trace de la pile de sortie s'il y a un argument de trace
print "{:=^30}".format(" STACK TRACE ")
print stack_trace.strip()
else:
sys.stderr.write(
"{0}: {1}\n".format(e_type, e.message))
sys.exit(1)
En d'autres termes, le modèle de la fonction principale est le suivant.
__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 Correction
# len(argv) ==C'était 1 au lieu de 0. Excusez-moi
parser.parse_args(["-h"]) #Afficher un message d'aide s'il n'y a pas d'arguments de ligne de commande
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 Addendum: vous pouvez obtenir le nom de l'erreur avec ce
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)
Du code ci-dessus
if len(sys.argv) == 0:
parser.parse_args(["-h"])
Il y a eu une erreur dans cette partie. Correctement
if len(sys.argv) == 1: # 0 -> 1
parser.parse_args(["-h"])
Le but de ce code (pour obtenir un message d'aide de l'analyseur) est que dans le cas d'argparse, si vous démarrez l'application sans définir d'arguments de ligne de commande,
usage: setup-script [-h] [-l] [--stack-trace] formula project
setup-script: error: too few arguments
Puisqu'un tel message d'erreur (signifiant qu'il n'y a pas d'argument) est affiché, si sys.argv
vaut 1 avec l'intention de ne pas émettre cette erreur,parser.parse_args (["-h"])
Le message d'aide est émis sous la forme.
J'ai appris que vous pouvez utiliser type (e) .__ name__
pour obtenir le nom de l'erreur à partir de l'objet d'erreur.
Recommended Posts