Ich möchte argparse verwenden, um boolesche Befehlszeilenargumente zu analysieren, die als "--foo True" oder "--foo False" geschrieben sind. Zum Beispiel:
my_program --my_boolean_flag False
Der folgende Testcode macht jedoch nicht das, was ich möchte:
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)
Leider parsed_args.my_bool
bewertet zu True
. Dies ist auch dann der Fall, wenn ich mich cmd_line
zu bin ["--my_bool", ""]
, was überraschend ist, da es sich um eine bool("")
Bewertung handelt False
.
Wie kann ich argparse zu analysieren "False"
, "F"
und ihre unteren Gehäusevarianten zu sein False
?
python
boolean
argparse
command-line-parsing
SuperElectric
quelle
quelle
parser.add_argument('--feature', dest='feature', default=False, action='store_true')
. Diese Lösung garantiert, dass Sie immer einenbool
Typ mit WertTrue
oder erhaltenFalse
. (Diese Lösung hat eine Einschränkung: Ihre Option muss einen Standardwert haben.)parser.add_argument('--feature', dest='feature', type=lambda x:bool(distutils.util.strtobool(x)))
. Wenn die Option verwendet wird, stellt diese Lösung einenbool
Typ mit dem Wert vonTrue
oder sicherFalse
. Wenn die Option nicht verwendet wird, erhalten SieNone
. (distutils.util.strtobool(x)
ist aus einer anderen Stackoverflow-Frage )parser.add_argument('--my_bool', action='store_true', default=False)
Antworten:
Noch eine andere Lösung unter Verwendung der vorherigen Vorschläge, jedoch mit dem "richtigen" Analysefehler von
argparse
:Dies ist sehr nützlich, um Schalter mit Standardwerten zu erstellen. zum Beispiel
erlaubt mir zu verwenden:
und verwenden Sie weiterhin einen Standardwert (spezifisch für die Benutzereinstellungen). Ein (indirekt verwandter) Nachteil dieses Ansatzes ist, dass die 'Nargs' möglicherweise ein Positionsargument auffangen - siehe diese verwandte Frage und diesen Argparse-Fehlerbericht .
quelle
str2bool(v)
könnte durch ersetzt werdenbool(distutils.util.strtobool(v))
. Quelle: stackoverflow.com/a/18472142/2436175if args.nice:
beacuse gesetzt ist, wenn das Argument auf False gesetzt ist, es die Bedingung niemals bestehen wird. Wenn dieses Recht dann ist vielleicht ist es besser , Liste zurückzukehren ausstr2bool
Funktion und Setlist alsconst
Parameter, wie diese[True]
,[False]
. Korrigieren Sie mich, wenn ich falschIch denke, ein kanonischerer Weg, dies zu tun, ist über:
und
argparse
unterstützt diese Version gut:Wenn Sie die
--arg <True|False>
Version wirklich wollen , können Sie sie natürlichast.literal_eval
als "Typ" oder als benutzerdefinierte Funktion übergeben ...quelle
type=bool
sofort funktionieren sollte (betrachten Sie Positionsargumente!). Selbst wenn Sie zusätzlich angebenchoices=[False,True]
, werden sowohl "False" als auch "True" als "True" eingestuft (aufgrund einer Umwandlung von "String" in "Bool"?). Vielleicht verwandtes Problembool()
Funktion tun soll oder was Argparse akzeptieren solltype=fn
? Alleargparse
Prüfungenfn
sind aufrufbar. Es wird erwartetfn
, dass ein Zeichenfolgenargument verwendet und ein Wert zurückgegeben wird. Das Verhalten vonfn
liegt in der Verantwortung des Programmierers, nichtargparse's
.Ich empfehle mgilson Antwort aber mit einer unvereinbaren Gruppe ,
so dass Sie nicht verwenden können ,
--feature
und--no-feature
zur gleichen Zeit.und
aber nicht
Skript:
Sie können diesen Helfer dann verwenden, wenn Sie viele davon festlegen möchten:
quelle
add_argument
wird mit aufgerufendest='feature'
.set_defaults
heißt mitfeature=True
. Verstehen?--flag False
, sollte ein Teil der SO-Antworten sich darauf beziehen, WAS sie zu lösen versuchen, und nicht nur darauf, wie. Es sollte überhaupt kein Grund zu tun ,--flag False
oder--other-flag True
und dann einige benutzerdefinierten Parser verwenden , um die Zeichenfolge in einen boolean zu konvertieren ..action='store_true'
undaction='store_false'
sind die besten Möglichkeiten boolean Fahnen zu verwenden... can be “don’t do that”, but it should also include “try this instead”
die (zumindest für mich) Antworten impliziert, bei Bedarf tiefer gehen. Es gibt definitiv Zeiten, in denen einige von uns, die Fragen stellen, von Anleitungen zu besseren / besten Praktiken usw. profitieren können. Eine Antwort "wie angegeben" tut dies oft nicht. Abgesehen davon ist Ihre Frustration über Antworten, die oft von zu viel (oder falsch) ausgehen, völlig gültig.parser.set_defaults(feature=None)
help=
Eintrag für dieses Argument hinzufügen möchten , wohin soll es gehen? In demadd_mutually_exclusive_group()
Anruf? In einem oder beidenadd_argument()
Anrufen? Irgendwo anders?Hier ist eine weitere Variante ohne zusätzliche Zeile (n) zum Festlegen von Standardwerten. Dem Bool ist immer ein Wert zugewiesen, damit er ohne Vorabprüfung in logischen Anweisungen verwendet werden kann.
quelle
required=True
sonst erhalten Sie immer ein True Arg.python3 test.py --do-something False
fehlschlägterror: unrecognized arguments: False
, wird die Frage nicht wirklich beantwortet.Einzeiler:
quelle
type=lambda x: (str(x).lower() in ['true','1', 'yes'])
Es scheint einige Verwirrung darüber zu geben, was
type=bool
undtype='bool'
was bedeuten könnte. Sollte einer (oder beide) bedeuten, dass die Funktion ausgeführtbool()
oder ein Boolescher Wert zurückgegeben wird? Wie es steht,type='bool'
bedeutet nichts.add_argument
gibt einen'bool' is not callable
Fehler aus, als ob Sie verwendet hättentype='foobar'
, odertype='int'
.Hat
argparse
aber eine Registrierung, mit der Sie Schlüsselwörter wie diese definieren können. Es wird meistens verwendet füraction
zB `action = 'store_true'. Sie können die registrierten Schlüsselwörter sehen mit:welches ein Wörterbuch anzeigt
Es sind viele Aktionen definiert, aber nur ein Typ, der Standardtyp
argparse.identity
.Dieser Code definiert ein 'bool'-Schlüsselwort:
parser.register()
ist nicht dokumentiert, aber auch nicht versteckt. Zum größten Teil muss der Programmierer nicht darüber Bescheid wissentype
undaction
Funktions- und Klassenwerte annehmen. Es gibt viele Beispiele für Stapelüberläufe zum Definieren benutzerdefinierter Werte für beide.Falls dies aus der vorherigen Diskussion nicht ersichtlich ist,
bool()
bedeutet dies nicht "Parse a String". Aus der Python-Dokumentation:Vergleichen Sie dies mit
quelle
Ich habe nach dem gleichen Problem gesucht und imho ist die hübsche Lösung:
und damit den String wie oben vorgeschlagen in einen Booleschen Wert analysieren.
quelle
distutils.util.strtobool(v)
.distutils.util.strtobool
Rückgabe 1 oder 0 ist kein tatsächlicher Boolescher Wert.Ein ganz ähnlicher Weg ist zu verwenden:
und wenn Sie das Argument --feature in Ihrem Befehl setzen
Das Argument ist True, wenn Sie den Typ --feature nicht festlegen. Die Standardeinstellung für Argumente ist immer False!
quelle
--feature False
Zusätzlich zu dem, was @mgilson gesagt hat, sollte beachtet werden, dass es auch eine
ArgumentParser.add_mutually_exclusive_group(required=False)
Methode gibt, die es trivial macht, dies durchzusetzen,--flag
und--no-flag
nicht gleichzeitig verwendet wird.quelle
Dies funktioniert für alles, was ich erwarte:
Der Code:
quelle
_str_to_bool(s)
, um sies = s.lower()
einmal zu konvertieren , dann zu testenif s not in {'true', 'false', '1', '0'}
und schließlichreturn s in {'true', '1'}
.Ein einfacherer Weg wäre, wie unten zu verwenden.
quelle
Am einfachsten. Es ist nicht flexibel, aber ich bevorzuge Einfachheit.
BEARBEITEN: Wenn Sie der Eingabe nicht vertrauen, verwenden Sie sie nicht
eval
.quelle
eval
ist eine eingebaute Funktion. docs.python.org/3/library/functions.html#eval Dies kann jede unäre Funktion sein, die andere, flexiblere Ansätze nutzen.Der einfachste Weg wäre, Entscheidungen zu treffen :
Nicht übergeben --my-flag wird als False ausgewertet. Die erforderliche = True- Option kann hinzugefügt werden, wenn der Benutzer immer explizit eine Auswahl angeben soll.
quelle
Ich denke, der kanonischste Weg wird sein:
quelle
quelle
Der einfachste und korrekteste Weg ist
Beachten Sie, dass True-Werte y, yes, t, true, on und 1 sind. falsche Werte sind n, no, f, false, off und 0. Löst ValueError aus, wenn val etwas anderes ist.
quelle
Schnell und einfach, aber nur für Argumente 0 oder 1:
Die Ausgabe ist nach dem Aufruf vom Terminal "False":
quelle
Ähnlich wie @Akash, aber hier ist ein anderer Ansatz, den ich verwendet habe. Es verwendet
str
als,lambda
weil Pythonlambda
mir immer ein fremdes Gefühl gibt.quelle
Als Verbesserung der Antwort von @Akash Desarda könnten Sie dies tun
Und es unterstützt
python test.py --foo
quelle