Ce dont j'ai besoin c'est:
pro [-a xxx | [-b yyy -c zzz]]
J'ai essayé cela mais ne fonctionne pas. Est-ce que quelqu'un peut me donner un coup de main?
group= parser.add_argument_group('Model 2')
group_ex = group.add_mutually_exclusive_group()
group_ex.add_argument("-a", type=str, action = "store", default = "", help="test")
group_ex_2 = group_ex.add_argument_group("option 2")
group_ex_2.add_argument("-b", type=str, action = "store", default = "", help="test")
group_ex_2.add_argument("-c", type=str, action = "store", default = "", help="test")
Merci!
Réponses:
add_mutually_exclusive_group
ne rend pas un groupe entier mutuellement exclusif. Il rend les options au sein du groupe mutuellement exclusives.Ce que vous recherchez, ce sont des sous - commandes . Au lieu de prog [-a xxxx | [-b yyy -c zzz]], vous auriez:
prog command 1 -a: ... command 2 -b: ... -c: ...
Pour appeler avec le premier ensemble d'arguments:
Pour appeler avec le deuxième ensemble d'arguments:
Vous pouvez également définir les arguments de la sous-commande comme positionnels.
Un peu comme git ou svn:
Exemple de travail
# create the top-level parser parser = argparse.ArgumentParser(prog='PROG') parser.add_argument('--foo', action='store_true', help='help for foo arg.') subparsers = parser.add_subparsers(help='help for subcommand') # create the parser for the "command_1" command parser_a = subparsers.add_parser('command_1', help='command_1 help') parser_a.add_argument('a', type=str, help='help for bar, positional') # create the parser for the "command_2" command parser_b = subparsers.add_parser('command_2', help='help for command_2') parser_b.add_argument('-b', type=str, help='help for b') parser_b.add_argument('-c', type=str, action='store', default='', help='test')
Essaye-le
>>> parser.print_help() usage: PROG [-h] [--foo] {command_1,command_2} ... positional arguments: {command_1,command_2} help for subcommand command_1 command_1 help command_2 help for command_2 optional arguments: -h, --help show this help message and exit --foo help for foo arg. >>> >>> parser.parse_args(['command_1', 'working']) Namespace(a='working', foo=False) >>> parser.parse_args(['command_1', 'wellness', '-b x']) usage: PROG [-h] [--foo] {command_1,command_2} ... PROG: error: unrecognized arguments: -b x
Bonne chance.
la source
[[-a <val>] | [-b <val1> -c <val2>]]
[-a xxx | [-b yyy -c zzz]]
Alors que la réponse de Jonathan convient parfaitement aux options complexes, il existe une solution très simple qui fonctionnera pour les cas simples, par exemple 1 option exclut 2 autres options comme dans
ou même comme dans la question initiale:
Voici comment je le ferais:
parser = argparse.ArgumentParser() # group 1 parser.add_argument("-q", "--query", help="query", required=False) parser.add_argument("-f", "--fields", help="field names", required=False) # group 2 parser.add_argument("-a", "--aggregation", help="aggregation", required=False)
J'utilise ici les options données à un wrapper de ligne de commande pour interroger un mongodb. L'
collection
instance peut appeler la méthodeaggregate
ou la méthodefind
avec des arguments optionnelsquery
etfields
, par conséquent, vous voyez pourquoi les deux premiers arguments sont compatibles et le dernier ne l'est pas.Alors maintenant, je cours
parser.parse_args()
et vérifie son contenu:args = parser().parse_args() print args.aggregation if args.aggregation and (args.query or args.fields): print "-a and -q|-f are mutually exclusive ..." sys.exit(2)
Bien sûr, ce petit hack ne fonctionne que pour des cas simples et cela deviendrait un cauchemar de vérifier toutes les options possibles si vous avez de nombreuses options et groupes mutuellement exclusifs. Dans ce cas, vous devriez diviser vos options en groupes de commande comme Jonathan l'a suggéré.
la source
parser.error("-a and -q ...")
. De cette façon, l'aide à l'utilisation complète sera imprimée automatiquement.q
etf
sont requis dans le premier groupe est l'utilisateur, (2) l'un ou l'autre des groupes est requis. Et cela rend la solution «simple» plus si simple. Je suis donc d'accord pour dire que c'est plus un hack pour un script artisanal, mais pas une vraie solutionIl existe un patch python (en développement) qui vous permettrait de faire cela.
http://bugs.python.org/issue10984
L'idée est de permettre le chevauchement de groupes mutuellement exclusifs. Cela
usage
pourrait donc ressembler à:Changer le code argparse pour pouvoir créer deux groupes comme celui-ci était la partie la plus facile. La modification du
usage
code de formatage a nécessité l'écriture d'une personnalisationHelpFormatter
.Dans
argparse
, les groupes d'actions n'affectent pas l'analyse. Ils ne sont qu'unhelp
outil de formatage. Dans lehelp
, les groupes mutuellement exclusifs affectent uniquement lausage
ligne. Lors de l'analyse, leparser
utilise les groupes mutuellement exclusifs pour construire un dictionnaire de conflits potentiels (a
ne peut pas se produire avecb
ouc
,b
ne peut pas se produire aveca
, etc.), puis génère une erreur en cas de conflit.Sans ce correctif argparse, je pense que votre meilleur choix est de tester l'espace de noms produit par
parse_args
vous-même (par exemple si les deuxa
etb
ont des valeurs non par défaut), et de déclencher votre propre erreur. Vous pouvez même utiliser le propre mécanisme d'erreur de l'analyseur.parser.error('custom error message')
la source