2015-10-08 4 views
1

Je suis en train de créer un programme comme une tâche dans mon école, j'en ai fini avec elle sauf une chose. Nous devons faire sortir le programme avec différents codes en fonction de la façon dont l'exécution s'est déroulée. Dans mon programme, je suis en train de traiter les options en utilisant "argparse" et quand j'utilise des fonctions intégrées comme "version", j'ai réussi à remplacer le code de sortie, mais si j'écris une option qui n'existe pas, alors ne fonctionne pas. Il me donne le "message non reconnu" -message, et sort avec le code "0", j'en ai besoin pour sortir avec le code 1. Y a-t-il un moyen de le faire? Été me rendre fou, ont lutté avec lui pendant des jours maintenant ...Python3 override erreur argparse

Merci d'avance! /feeloor

Répondre

0

Utilisez sys.exit (code retour) pour quitter avec des codes particuliers. Évidemment, sur les machines Linux, vous n'avez pas besoin d'un décalage de 8 bits pour obtenir le bon code de retour.

+0

Oui, que je sais, la question est comment remplacer les erreurs argparse? Parce que quand une option n'est pas reconnue, elle sort automatiquement avec le code d'erreur 0, je veux la remplacer pour que je puisse la changer pour sortir avec le code 1 ... – feeloor

+0

use try except block pour attraper l'erreur et selon l'exception exit avec différents codes ... indice: utilisez des méthodes comme sys.exc_info() afin de détecter le type d'exception .. –

0

Pour obtenir quelque chose comme ceci, héritez de argparse.ArgumentParser et réimplémentez la méthode exit (ou peut-être la méthode error si vous le souhaitez).

Par exemple:

class Parser(argparse.ArgumentParser): 
    # the default status on the parent class is 0, we're 
    # changing it to be 1 here ... 
    def exit(self, status=1, message=None): 
     return super().exit(status, message) 
+0

C'est quelque chose que j'imagine que je vais devoir faire, mais j'ai besoin de voir réellement quelle est l'erreur et en fonction de l'erreur donne le code de sortie, car comme je l'ai dit, le statut de sortie "1" est pour quand les options sont mal saisies, "0" quand le programme se termine avec succès et "2" quand une "commande" est fausse ... comprendre comment je veux dire, désolé si je suis un peu flou .. – feeloor

+0

Ensuite, remplacez plus de méthodes sur 'ArgumentParser', comme l'initiative' error' ... et tout cela ... – donkopotamus

+0

Ye c'est ce que je veux faire, mais Je n'arrive pas à trouver leur "nom" ou comment le faire? Je suis assez nouveau pour python désolé .. – feeloor

0

De la documentation Python argparse

https://docs.python.org/3/library/argparse.html#exiting-methods

16.4.5.9. Exiting methods 

ArgumentParser.exit(status=0, message=None) 

    This method terminates the program, exiting with the specified status and, if given, it prints a message before that. 

ArgumentParser.error(message) 

    This method prints a usage message including the message to the standard error and terminates the program with a status code of 2. 

Ils ont tous deux obtenir un message, et le transmettre. error ajoute usage et le transmet au exit. Vous pouvez personnaliser les deux dans un analyseur sous-classé.

Il existe également des exemples d'erreur de capture et de redirection du fichier unittest, test/test_argparse.py.

Un problème avec l'utilisation d'une enveloppe try/except est que l'information error est écrit à sys.stderr, et non repris dans le sys.exc_info.

In [117]: try: 
    parser.parse_args(['ug']) 
except: 
    print('execinfo:',sys.exc_info()) 
    .....:  
usage: ipython3 [-h] [--test TEST] [--bar TEST] test test 
ipython3: error: the following arguments are required: test 
execinfo: (<class 'SystemExit'>, SystemExit(2,), <traceback object at 0xb31fb34c>) 

Le numéro de sortie est disponible dans exc_info, mais pas le message. Une option consiste à rediriger sys.stderr en même temps que le bloc try/except.

Voici un exemple de changer la méthode exit et enveloppant l'appel dans un bloc try:

In [155]: 
def altexit(status, msg): 
    print(status, msg) 
    raise ValueError(msg) 
    .....: 
In [156]: parser.exit=altexit 

In [157]: 
try:      
    parser.parse_args(['--ug','ug','ug']) 
except ValueError:  
    msg = sys.exc_info()[1] 
    .....:  
usage: ipython3 [-h] [--test TEST] [--bar TEST] test test 
2 ipython3: error: unrecognized arguments: --ug 

In [158]: msg 
Out[158]: ValueError('ipython3: error: unrecognized arguments: --ug\n') 

Python me permet de remplacer les méthodes d'objets existants. Je ne recommande pas cela dans le code de production, mais c'est pratique pour essayer des idées. Je capture l'erreur (mon choix de ValueError est arbitraire), et enregistre le message pour un affichage ou un test ultérieur.

Généralement, le type d'erreur (par exemple TypeError, ValueError, etc.) fait partie de l'API publique, mais le texte d'erreur ne l'est pas. Il peut être affiné d'une version de Python à l'autre sans beaucoup de notification. Vous testez donc les détails du message à vos risques et périls.

0

J'ai résolu le problème en attrapant SystemExit et en déterminant quelle erreur en testant et en comparant simplement. Merci pour toute l'aide les gars!