J'utilise argparse
pour un programme Python qui peut -process
, -upload
ou les deux:
parser = argparse.ArgumentParser(description='Log archiver arguments.')
parser.add_argument('-process', action='store_true')
parser.add_argument('-upload', action='store_true')
args = parser.parse_args()
Le programme n'a pas de sens sans au moins un paramètre. Comment puis-je configurer argparse
pour forcer au moins un paramètre à être choisi?
METTRE À JOUR:
Suite aux commentaires: Quelle est la manière pythonique de paramétrer un programme avec au moins une option?
-x
est universellement un drapeau et facultatif. Coupez le-
si nécessaire.process
le comportement par défaut (sans avoir besoin de spécifier aucune option) et permettre à l'utilisateur de le changerupload
si cette option est définie? Habituellement, les options doivent être facultatives, d'où le nom. Les options obligatoires doivent être évitées (cela se trouve également dans laargparse
documentation).Réponses:
la source
argparse
n'y a pas d'option intégrée pour cela.la source
vars()
, qui est également utile pour passer des options soigneusement nommées à un constructeur avec **.vars
. Je viens de le faire.__dict__
et je me suis senti stupide avant.Si ce n'est pas la partie `` ou les deux '' (j'ai initialement manqué ceci), vous pouvez utiliser quelque chose comme ceci:
Cependant, ce serait probablement une meilleure idée d'utiliser des sous-commandes à la place.
la source
--process
OU--upload
, pas XOR. Cela empêche les deux options d'être définies en même temps.-x
et--xxx
sont généralement des paramètres optionnels.Je sais que c'est vieux comme de la saleté, mais la façon d'exiger une option mais d'en interdire plus d'une (XOR) est comme ceci:
Production:
la source
Examen des exigences
argparse
(je vais ignorer celui-ci)Il existe également des exigences implicites lorsque l'on vit en ligne de commande:
Exemple de solution utilisant
docopt
(fichiermanagelog.py
):Essayez de l'exécuter:
Montrez l'aide:
Et utilisez-le:
Alternative courte
short.py
Il peut y avoir une variante encore plus courte:
L'utilisation ressemble à ceci:
Notez qu'au lieu de valeurs booléennes pour les clés "process" et "upload", il y a des compteurs.
Il s'avère que nous ne pouvons pas empêcher la duplication de ces mots:
Conclusions
Concevoir une bonne interface de ligne de commande peut parfois être difficile.
Il existe plusieurs aspects du programme basé sur la ligne de commande:
argparse
offre beaucoup, mais restreint les scénarios possibles et peut devenir très complexe.Avec les
docopt
choses vont beaucoup plus court tout en préservant la lisibilité et en offrant un haut degré de flexibilité. Si vous parvenez à obtenir des arguments analysés à partir du dictionnaire et à effectuer certaines conversions (en entiers, en ouvrant des fichiers ..) manuellement (ou par une autre bibliothèque appeléeschema
), vous pouvez trouver ladocopt
bonne solution pour l'analyse en ligne de commande.la source
Si vous avez besoin d'un programme python pour s'exécuter avec au moins un paramètre, ajoutez un argument qui n'a pas le préfixe d'option (- ou - par défaut) et défini
nargs=+
(Minimum d'un argument requis). Le problème avec cette méthode que j'ai trouvé est que si vous ne spécifiez pas l'argument, argparse générera une erreur "trop peu d'arguments" et n'imprimera pas le menu d'aide. Si vous n'avez pas besoin de cette fonctionnalité, voici comment le faire dans le code:Je pense que lorsque vous ajoutez un argument avec les préfixes d'option, nargs régit l'ensemble de l'analyseur d'arguments et pas seulement l'option. (Ce que je veux dire, c'est que si vous avez un
--option
indicateur avecnargs="+"
, alors--option
flag attend au moins un argument. Si vous avezoption
avecnargs="+"
, il attend au moins un argument global.)la source
choices=['process','upload']
à cet argument.Pour http://bugs.python.org/issue11588 , j'explore des moyens de généraliser
mutually_exclusive_group
concept pour gérer des cas comme celui-ci.Avec ce développement
argparse.py
, https://github.com/hpaulj/argparse_issues/blob/nested/argparse.py je suis capable d'écrire:qui produit ce qui suit
help
:Cela accepte les entrées comme '-u', '-up', '--proc --up' etc.
Il finit par exécuter un test similaire à https://stackoverflow.com/a/6723066/901925 , bien que le message d'erreur doive être plus clair:
Je me demande:
les paramètres sont-ils
kind='any', required=True
suffisamment clairs (acceptez l'un des groupes; au moins un est requis)?l'utilisation est-elle
(-p | -u)
claire? Un groupe mutuellement_exclusif requis produit la même chose. Existe-t-il une notation alternative?L'utilisation d'un groupe comme celui-ci est-elle plus intuitive qu'un
phihag's
simple test?la source
add_usage_group
sur cette page: docs.python.org/2/library/argparse.html ; pouvez-vous fournir un lien vers la documentation correspondante?La meilleure façon de le faire est d'utiliser le module intégré python add_mutually_exclusive_group .
Si vous voulez qu'un seul argument soit sélectionné par la ligne de commande, utilisez simplement required = True comme argument pour le groupe
la source
Peut-être utiliser des sous-analyseurs?
--help
Montre maintenant :Vous pouvez également ajouter des options supplémentaires à ces sous-analyseurs. Au lieu d'utiliser cela,
dest='subparser_name'
vous pouvez également lier des fonctions à appeler directement sur une sous-commande donnée (voir la documentation).la source
Cela atteint le but et cela sera également corrigé dans la
--help
sortie générée automatiquement par argparse , qui est à mon avis ce que la plupart des programmeurs sensés veulent (fonctionne également avec des arguments optionnels):Documents officiels à ce sujet: https://docs.python.org/3/library/argparse.html#choices
la source
Utilisez append_const pour une liste d'actions, puis vérifiez que la liste est remplie:
Vous pouvez même spécifier les méthodes directement dans les constantes.
la source