Chciałbym użyć argparse do analizy argumentów wiersza poleceń boolean zapisanych jako „--foo True” lub „--foo False”. Na przykład:
my_program --my_boolean_flag False
Jednak poniższy kod testowy nie robi tego, co chciałbym:
import argparse
parser = argparse.ArgumentParser(description="My parser")
parser.add_argument("--my_bool", type=bool)
cmd_line = ["--my_bool", "False"]
parsed_args = parser.parse(cmd_line)
Niestety parsed_args.my_bool
ocenia True
. Jest tak nawet w przypadku, kiedy zmieni cmd_line
się["--my_bool", ""]
, co jest zaskakujące, ponieważ bool("")
evalutates do False
.
Jak mogę uzyskać argparse do analizowania "False"
, "F"
a ich małymi literami warianty być False
?
python
boolean
argparse
command-line-parsing
SuperElectric
źródło
źródło
parser.add_argument('--feature', dest='feature', default=False, action='store_true')
. To rozwiązanie zagwarantuje, że zawsze otrzymaszbool
typ o wartościTrue
lubFalse
. (To rozwiązanie ma ograniczenie: twoja opcja musi mieć wartość domyślną.)parser.add_argument('--feature', dest='feature', type=lambda x:bool(distutils.util.strtobool(x)))
. Gdy zostanie użyta opcja, to rozwiązanie zapewnibool
typ o wartościTrue
lubFalse
. Gdy opcja nie zostanie użyta, otrzymaszNone
. (distutils.util.strtobool(x)
pochodzi z innego pytania dotyczącegoparser.add_argument('--my_bool', action='store_true', default=False)
Odpowiedzi:
Jeszcze inne rozwiązanie wykorzystujące poprzednie sugestie, ale z „poprawnym” błędem analizy z
argparse
:Jest to bardzo przydatne do tworzenia przełączników z wartościami domyślnymi; na przykład
pozwala mi używać:
i nadal używaj wartości domyślnej (specyficznej dla ustawień użytkownika). Jednym (pośrednio powiązanym) minusem tego podejścia jest to, że „nargs” może złapać argument pozycyjny - zobacz to powiązane pytanie i ten raport o błędach argparse .
źródło
str2bool(v)
można zastąpićbool(distutils.util.strtobool(v))
. Źródło: stackoverflow.com/a/18472142/2436175if args.nice:
ponieważ argument jest ustawiony na False, nigdy nie spełni warunku. Jeśli jest to prawda, to może lepiej jest wrócić z listystr2bool
funkcji i ustawić listy jakoconst
parametru, jak ta[True]
,[False]
. Popraw mnie, jeśli się mylęMyślę, że bardziej kanonicznym sposobem na to jest:
i
argparse
ładnie obsługuje tę wersję:Oczywiście, jeśli naprawdę chcesz
--arg <True|False>
wersję, możesz przekazać jąast.literal_eval
jako „typ” lub funkcję zdefiniowaną przez użytkownika ...źródło
type=bool
powinien działać od razu (rozważ argumenty pozycyjne!). Nawet jeśli dodatkowo określiszchoices=[False,True]
, to zarówno „Fałsz”, jak i „Prawda” są uważane za Prawda (ze względu na rzut z łańcucha na bool?). Być może związany z tym problembool()
powinna zrobić funkcja , lub w co powinien się przyjąć argparsetype=fn
? Wszystkieargparse
czekifn
są na żądanie. Oczekuje,fn
że weźmie jeden argument ciągu i zwróci wartość. Zachowaniefn
jest obowiązkiem programisty, a nieargparse's
.Polecam odpowiedź mgilson, ale z ekskluzywnej grupy wzajemnie
tak, że nie można używać
--feature
i--no-feature
w tym samym czasie.i
ale nie
Scenariusz:
Możesz użyć tego pomocnika, jeśli chcesz ustawić wiele z nich:
źródło
add_argument
jest wywoływany zdest='feature'
.set_defaults
nazywa się za pomocąfeature=True
. Rozumiesz?--flag False
, część odpowiedzi SO powinna dotyczyć tego, co próbują rozwiązać, a nie tylko JAK. Nie powinno być absolutnie żadnego powodu, aby zrobić--flag False
albo--other-flag True
, a następnie użyć trochę niestandardowy parser przekonwertować ciąg na wartość logiczną ..action='store_true'
iaction='store_false'
są najlepsze sposoby korzystania logicznych flagi... can be “don’t do that”, but it should also include “try this instead”
która (przynajmniej dla mnie) implikuje odpowiedzi, powinna w miarę potrzeby sięgać głębiej. Zdecydowanie są chwile, kiedy niektórzy z nas, którzy zadają pytania, mogą skorzystać z porad dotyczących lepszych / najlepszych praktyk itp. Odpowiedzi „jak stwierdzono” często tego nie robią. To powiedziawszy, twoja frustracja odpowiedziami często zakładającymi zbyt wiele (lub niepoprawnie) jest całkowicie uzasadniona.parser.set_defaults(feature=None)
help=
wpis do tego argumentu, gdzie powinien on iść? Wadd_mutually_exclusive_group()
rozmowie? W jednym lub obuadd_argument()
połączeniach? Gdzieś indziej?Oto kolejna odmiana bez dodatkowych wierszy / s, aby ustawić wartości domyślne. Wartość bool zawsze ma przypisaną wartość, dzięki czemu można jej używać w instrukcjach logicznych bez wstępnej kontroli.
źródło
required=True
przeciwnym razie zawsze otrzymasz True Arg.python3 test.py --do-something False
nie udaje sięerror: unrecognized arguments: False
, więc tak naprawdę nie odpowiada na pytanie.oneliner:
źródło
type=lambda x: (str(x).lower() in ['true','1', 'yes'])
Wydaje się, że istnieje pewne zamieszanie co do tego
type=bool
itype='bool'
może oznaczać. Czy jeden (lub oba) powinien oznaczać „uruchomić funkcjębool()
, czy„ zwrócić wartość logiczną ”? W obecnej formietype='bool'
nic nie znaczy.add_argument
daje'bool' is not callable
błąd, taki sam jak w przypadku użyciatype='foobar'
, lubtype='int'
.Ale
argparse
ma rejestr, który pozwala zdefiniować takie słowa kluczowe. Jest używany głównie doaction
, np. `Action = 'store_true'. Możesz zobaczyć zarejestrowane słowa kluczowe za pomocą:który wyświetla słownik
Istnieje wiele działań zdefiniowana, ale tylko jeden rodzaj, wartość domyślna,
argparse.identity
.Ten kod definiuje słowo kluczowe „bool”:
parser.register()
nie jest udokumentowany, ale także nie jest ukryty. W większości przypadków programista nie musi o tym wiedzieć, ponieważtype
iaction
funkcja odbioru i klasy wartości. Istnieje wiele przykładów przepływu stosu definiowania niestandardowych wartości dla obu.Jeśli nie jest to oczywiste z poprzedniej dyskusji,
bool()
nie oznacza to „parsowania łańcucha”. Z dokumentacji Python:Porównaj to z
źródło
Szukałem tego samego problemu, a imho ładnym rozwiązaniem jest:
i użycie go do parsowania łańcucha na wartość logiczną, jak sugerowano powyżej.
źródło
distutils.util.strtobool(v)
.distutils.util.strtobool
powroty 1 lub 0, a nie rzeczywiste logiczna.Całkiem podobny sposób polega na użyciu:
a jeśli ustawisz argument - funkcja w swoim poleceniu
argumentem będzie Prawda, jeśli nie ustawisz typu - funkcja argumentami domyślnie jest zawsze Fałsz!
źródło
--feature False
Oprócz tego, co powiedział @mgilson, należy zauważyć, że istnieje również
ArgumentParser.add_mutually_exclusive_group(required=False)
metoda, która sprawiłaby, że wymuszenie tego byłoby trywialne--flag
i--no-flag
nie jest używane jednocześnie.źródło
Działa to na wszystko, czego oczekuję:
Kod:
źródło
_str_to_bool(s)
aby przekonwertowaćs = s.lower()
, potem przetestowaćif s not in {'true', 'false', '1', '0'}
i wreszciereturn s in {'true', '1'}
.Prostszym sposobem byłoby użycie jak poniżej.
źródło
Najprostszy Nie jest elastyczny, ale wolę prostotę.
EDYCJA: Jeśli nie ufasz danych wejściowych, nie używaj
eval
.źródło
eval
jest wbudowaną funkcją. docs.python.org/3/library/functions.html#eval Może to być dowolna jednoargumentowa funkcja, którą wykorzystują inne, bardziej elastyczne podejścia.Najprostszym sposobem byłoby użycie opcji :
Nieprzekazanie - moja-flaga zwraca wartość False. Wymagane = True opcji można dodać, jeśli zawsze chcesz użytkownikowi podanie wyboru.
źródło
Myślę, że najbardziej kanonicznym sposobem będzie:
źródło
źródło
Najprostszym i najbardziej poprawnym sposobem jest
Zauważ, że wartościami True są y, tak, t, true, on i 1; fałszywe wartości to n, no, f, false, off i 0. Podnosi wartośćError, jeśli val jest czymś innym.
źródło
Szybko i łatwo, ale tylko dla argumentów 0 lub 1:
Wyjście będzie „False” po wywołaniu z terminala:
źródło
Podobne do @Akash, ale oto inne podejście, którego użyłem. Używa
str
niżlambda
dlatego, że pythonlambda
zawsze daje mi obce uczucia.źródło
Jako ulepszenie odpowiedzi @Akash Desarda możesz to zrobić
I obsługuje
python test.py --foo
źródło