Mam następujące wymagania:
./xyifier --prox --lport lport --rport rport
dla argumentu prox używam action = 'store_true', aby sprawdzić, czy jest obecny, czy nie. Nie potrzebuję żadnych argumentów. Ale jeśli ustawione jest --prox, potrzebuję również rport i lport. Czy istnieje łatwy sposób na zrobienie tego za pomocą argparse bez pisania niestandardowego kodowania warunkowego.
Więcej kodu:
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.')
Odpowiedzi:
Nie, w argparse nie ma opcji tworzenia wzajemnie obejmujących się zestawów opcji.
Najprostszym sposobem rozwiązania tego problemu byłoby:
źródło
parser.error
metodę, tego szukałem!if args.prox and (args.lport is None or args.rport is None):
args.lport is None
możesz po prostu użyćnot args.lport
. Myślę, że jest trochę bardziej pytoniczny.--lport
lub--rport
do0
, co może być prawidłowym wejściem do programu.Mówisz o warunkowo wymaganych argumentach. Podobnie jak @borntyping powiedział, że możesz sprawdzić błąd i zrobić
parser.error()
, lub możesz po prostu zastosować wymaganie związane z--prox
dodaniem nowego argumentu.Prostym rozwiązaniem na przykład może być:
W ten sposób
required
otrzymuje alboTrue
alboFalse
jako stosowane w zależności od tego, czy użytkownik--prox
. To również gwarantuje, że-lport
i-rport
mają niezależne zachowanie między sobą.źródło
ArgumentParser
może być używany do analizowania argumentów z listy innej niżsys.argv
, w takim przypadku zakończy się to niepowodzeniem.--prox=<value>
zostanie użyta składnia.Co powiesz na użycie
parser.parse_known_args()
metody, a następnie dodanie argumentów--lport
i--rport
argumentów jako wymaganych argumentów, jeśli--prox
jest obecny.Pamiętaj również, że możesz podać przestrzeń nazw
opts
wygenerowaną po pierwszym przeanalizowaniu podczas analizowania pozostałych argumentów za drugim razem. W ten sposób, po zakończeniu całego parsowania, będziesz mieć jedną przestrzeń nazw ze wszystkimi opcjami.Wady:
--prox
nie jest obecny, pozostałe dwie opcje zależne nie są nawet obecne w przestrzeni nazw. Chociaż w oparciu o Twój przypadek użycia, jeśli--prox
nie jest obecny, to, co dzieje się z innymi opcjami, nie ma znaczenia.--lport
i--rport
nie pokazuj się w wiadomościach pomocyźródło
Czy używasz
lport
kiedyprox
nie jest ustawione. Jeśli nie, dlaczego nie zrobićlport
irport
argumentowaćprox
? na przykładTo oszczędza użytkownikom pisania. Jest to równie łatwe do przetestowania,
if args.prox is not None:
jakif args.prox:
.źródło
a,b = args.prox
,a = args.prox[0]
itdPrzyjęta odpowiedź zadziałała dla mnie świetnie! Ponieważ cały kod jest uszkodzony bez testów, oto jak przetestowałem zaakceptowaną odpowiedź.
parser.error()
nie zgłaszaargparse.ArgumentError
błędu, zamiast tego kończy proces. Musisz przetestowaćSystemExit
.z pytest
z napisami
zainspirowany: Używanie unittest do testowania argparse - błędy wyjścia
źródło