J'ai une exigence comme suit:
./xyifier --prox --lport lport --rport rport
pour l'argument prox, j'utilise action = 'store_true' pour vérifier s'il est présent ou non. Je n'ai besoin d'aucun argument. Mais, si --prox est défini, j'ai également besoin de rport et de lport. Existe-t-il un moyen simple de faire cela avec argparse sans écrire de codage conditionnel personnalisé.
Plus de code:
non_int.add_argument('--prox', action='store_true', help='Flag to turn on proxy')
non_int.add_argument('--lport', type=int, help='Listen Port.')
non_int.add_argument('--rport', type=int, help='Proxy port.')
Réponses:
Non, il n'y a aucune option dans argparse pour créer des ensembles d'options mutuellement inclusifs .
La façon la plus simple de gérer cela serait:
la source
parser.error
méthode, c'est ce que je cherchais!if args.prox and (args.lport is None or args.rport is None):
args.lport is None
, vous pouvez simplement utilisernot args.lport
. Je pense que c'est un peu plus pythonique.--lport
ou--rport
à0
, ce qui pourrait être une entrée valide pour le programme.Vous parlez d'avoir des arguments conditionnellement requis. Comme @borntyping l'a dit, vous pouvez vérifier l'erreur et le faire
parser.error()
, ou vous pouvez simplement appliquer une exigence liée au--prox
moment où vous ajoutez un nouvel argument.Une solution simple pour votre exemple pourrait être:
De cette façon
required
reçoit soitTrue
ouFalse
selon que l'utilisateur est utilisé--prox
. Cela garantit également cela-lport
et-rport
avoir un comportement indépendant entre eux.la source
ArgumentParser
peut être utilisé pour analyser les arguments d'une liste autre quesys.argv
, auquel cas cela échouerait.--prox=<value>
syntaxe est utilisée.Que diriez-vous d'utiliser la
parser.parse_known_args()
méthode et d'ajouter ensuite les arguments--lport
et les--rport
arguments requis si les arguments--prox
sont présents.Gardez également à l'esprit que vous pouvez fournir l'espace de noms
opts
généré après la première analyse tout en analysant les arguments restants la deuxième fois. De cette façon, à la fin, une fois l'analyse terminée, vous aurez un seul espace de noms avec toutes les options.Désavantages:
--prox
n'est pas présent, les deux autres options dépendantes ne sont même pas présentes dans l'espace de noms. Bien que basé sur votre cas d'utilisation, si--prox
n'est pas présent, ce qui arrive aux autres options n'est pas pertinent.--lport
et--rport
n'apparaissent pas dans le message d'aidela source
Utilisez-vous
lport
quandprox
n'est pas défini. Sinon, pourquoi ne pas fairelport
etrport
argumentsprox
? par exempleCela évite à vos utilisateurs de taper. C'est aussi simple à tester
if args.prox is not None:
queif args.prox:
.la source
a,b = args.prox
,a = args.prox[0]
, etc.La réponse acceptée a très bien fonctionné pour moi! Puisque tout le code est cassé sans tests, voici comment j'ai testé la réponse acceptée.
parser.error()
ne génère pas d'argparse.ArgumentError
erreur, il quitte le processus. Vous devez testerSystemExit
.avec pytest
avec unittests
inspiré de: Utilisation d'unittest pour tester argparse - erreurs de sortie
la source