Ne pouvez pas obtenir argparse pour lire la chaîne de caractères entre guillemets avec des tirets-t-il?
Est-il un moyen de faire argparse reconnaître quoi que ce soit entre deux guillemets comme un seul argument? Il semble continuer de voir les tirets et en supposant que c'est le début d'une nouvelle option
J'ai quelque chose comme:
mainparser = argparse.ArgumentParser()
subparsers = mainparser.add_subparsers(dest='subcommand')
parser = subparsers.add_parser('queue')
parser.add_argument('-env', '--extraEnvVars', type=str,
help='String of extra arguments to be passed to model.')
...other arguments added to parser...
Mais quand je le lance:
python Application.py queue -env "-s WHATEVER -e COOL STUFF"
Il me donne:
Application.py queue: error: argument -env/--extraEnvVars: expected one argument
Si j'ai laisser tomber le premier tableau de bord, il fonctionne tout à fait bien, mais il est essentiel que je sois capable de passer en une chaîne de caractères avec des tirets en elle. J'ai essayé de s'échapper avec \ , ce qui le fait réussir, mais ajoute à la \ de la chaîne d'argument personne Ne sait comment contourner ce problème? Ce qui se passe si ou non -s est un argument dans l'analyseur.
EDIT: je suis à l'aide de Python 2.7.
EDIT2:
python Application.py -env " -env"
fonctionne parfaitement bien, mais
python Application.py -env "-env"
ne pas.
EDIT3: il Semble que ce soit effectivement un bug qui débattu déjà: http://www.gossamer-threads.com/lists/python/bugs/89529, http://python.6.x6.nabble.com/issue9334-argparse-does-not-accept-options-taking-arguments-beginning-with-dash-regression-from-optp-td578790.html. C'est seulement en 2.7 et pas dans optparse.
EDIT4: Le courant rapport de bug est: http://bugs.python.org/issue9334
- Quelle est la version de Python que vous utilisez?
- J'utilise Python 2.7.
- Cela fonctionne très bien pour moi sur Python 2.7. Avez-vous d'autres arguments configuré?
- Oui, un certain nombre d'entre eux. Aussi, -e est l'argument de l'un des subparsers de mon programme. Je vais poster une information plus complète sur l'extrait de code pour le rendre plus clair.
- Hm...je suis sûr. Tous mes autres options fonctionnent bien, et extraEnvVars ce qu'il est censé faire aussi longtemps que la chaîne ne commence pas par un tiret. Par exemple, python Application.py la file d'attente -env "-env" fonctionne très bien.
- BTW, "cité" ici est totalement discutable -- les guillemets sont consommés par le shell avant de
argparse
(ou l'interpréteur Python) a toute chance de bien qu'ils soient là ou pas.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez commencer à l'argument avec un espace
python tst.py -e ' -e blah'
comme un simple palliatif. Simplementlstrip()
l'option pour le mettre à la normale, si vous le souhaitez.Ou, si le premier "sous-argument" n'est pas un argument valide pour la fonction d'origine, alors vous ne devriez pas besoin de faire quoi que ce soit. C'est la seule raison qui
python tst.py -e '-s hi -e blah'
ne fonctionne pas est parce que-s
est une option valable pourtst.py
.Aussi, le optparse module, maintenant obsolète, fonctionne sans problème.
-a
, et simplement envoyé-a '-b hello'
et il a très bien fonctionné. Mais je suis en utilisant une autre version de Python, je suppose.-10:a 10:b
, mais il a travaillé pour' -10:a' 10:b
.Mise à jour de réponse:
Vous pouvez mettre un signe égal quand vous l'appelez:
Réponse originale à cette question:
Moi aussi, j'ai eu de la misère à faire ce que vous essayez de faire, mais il existe une solution de contournement construire en argparse, qui est le parse_known_args méthode. Cela permettra à tous les arguments que vous n'avez pas défini de passer à travers l'analyseur avec l'hypothèse que vous utilisez pour un sous-processus. Les inconvénients sont que vous ne recevrez pas de rapport d'erreur avec de mauvais arguments, et vous devrez vous assurer qu'il n'y a pas de collision entre vos options et vos sous-processus des options.
Une autre option pourrait être de forcer l'utilisateur à utiliser un plus à la place d'un moins:
et puis vous changez le '+' à '-' en post-traitement avant de passer à votre sous-processus.
nargs='+'
qui raconte-env
de la lecture dans une ou plusieurs cordes.python Application.py -env="-env"
Cette question est discutée plus en détail dans http://bugs.python.org/issue9334. L'essentiel de l'activité était en 2011. J'ai ajouté un patch de l'année dernière, mais il y en a un carnet de commandes de
argparse
patchs.En question est le potentiel d'ambiguïté dans une chaîne comme
'--env'
, ou"-s WHATEVER -e COOL STUFF"
lorsqu'il suit une option qui prend un argument.optparse
fait un simple gauche à droite analyser. La première--env
est un indicateur d'option qui prend un argument, de sorte qu'il consomme de l'autre, peu importe à quoi il ressemble.argparse
, d'autre part, des boucles à travers les cordes deux fois. D'abord, il catégorise comme " O " ou " A " (indicateur d'option ou argument). Sur la deuxième boucle il consomme, à l'aide d'unre
comme correspondant à un modèle de poignée variablenargs
valeurs. Dans ce cas, il semble que nous ayonsOO
, deux drapeaux et sans arguments.La solution lors de l'utilisation de
argparse
est de faire en sorte qu'un argument chaîne ne sera pas confus pour un indicateur d'option. Les possibilités qui ont été présentés ici (et dans la question bug) comprennent:Par lui-même
'--env'
ressemble à un drapeau (même lors de la cité, voirsys.argv
), mais lorsqu'il est suivi par d'autres chaînes qu'il ne l'est pas. Mais"-env one two"
a des problèmes parce qu'elle peut être analysée comme['-e','nv one two']
, un `-e " drapeau suivi par une chaîne de caractères (ou même plus d'options).--
etnargs=argparse.PARSER
peut également être utilisé pour forcerargparse
pour afficher toutes les chaînes de caractères suivantes en tant qu'arguments. Mais ils ne travaillent à la fin des listes d'arguments.Il y a un projet de patch dans issue9334 pour ajouter un
args_default_to_positional=True
mode. Dans ce mode, l'analyseur de classe uniquement les chaînes de caractères comme des indicateurs d'option si l'on peut clairement faire correspondre à des arguments définis par l'. Ainsi, '--un' dans '--env --un' est considéré comme comme un argument. Mais le second "--env' dans '----env env " serait encore d'être considéré comme un indicateur d'option.Expansion sur les cas dans
À l'aide de argparse avec des valeurs d'argument qui commencent par un tiret ("-")
produit
L' "-foo un" cas d'échec parce que le
-foo
est interprétée comme la-f
drapeau plus non spécifié extras. C'est la même action que permet-fe
être interprété comme['-f','-e']
.Si je change le
nargs
àREMAINDER
(pasPARSER
), tout ce qui est après-e
est interprété comme arguments pour que le drapeau:Tous les cas, les travaux. Notez que la valeur est une liste de. Et les guillemets ne sont pas nécessaires:
argparse.REMAINDER
est comme '*', sauf qu'il prend tout ce qui suit, si elle ressemble à un drapeau ou pas.argparse.PARSER
est plus comme '+', en ce qu'elle attend unpositional
comme argument premier. C'est lenargs
quesubparsers
utilise.Ce utilise de
REMAINDER
est documenté, https://docs.python.org/3/library/argparse.html#nargsnargs=argparse.PARSER
m'a aidé.python Application.py queue -env "-s WHATEVER -e COOL STUFF"
œuvres.queue -env "-foo"
soulève encore de l'erreur, parce que le standalone '-foo' (ou '--foo') est toujours interprété comme un drapeau. Les espaces après les apprent drapeau font une différence.Remarque: les valeurs de l'argument doivent être transmises uniquement à l'intérieur des guillemets, et cela ne fonctionne pas avec des guillemets simples