Überprüfen Sie, ob das optionale Argument argparse festgelegt ist oder nicht


112

Ich möchte prüfen, ob der Benutzer ein optionales Argument für argparse festgelegt hat oder nicht.

Kann ich mit isset sicher prüfen?

Etwas wie das:

if(isset(args.myArg)):
    #do something
else:
    #do something else

Funktioniert dies auch für Argumente vom Typ float / int / string?

Ich könnte einen Standardparameter festlegen und ihn überprüfen (z. B. myArg = -1 oder "" für einen String oder "NOT_SET"). Der Wert, den ich letztendlich verwenden möchte, wird jedoch erst später im Skript berechnet. Also würde ich es als Standard auf -1 setzen und es später auf etwas anderes aktualisieren. Dies scheint etwas ungeschickt im Vergleich zu der einfachen Überprüfung, ob der Wert vom Benutzer festgelegt wurde.


1
Was wäre isset()(Hinweis: Python ist kein PHP)? Meinten Sie hasattr()stattdessen vielleicht? Warum konfigurieren Sie argparse nicht so, dass stattdessen ein Standard für eine Option festgelegt wird?
Martijn Pieters

@MartijnPieters - ja, stimmt. Also kann ich einfach überprüfen, ob (args.myArg): ...
Madeleine P. Vincent

Antworten:


146

Ich denke, dass optionale Argumente (angegeben mit --) initialisiert werden, Nonewenn sie nicht angegeben werden. So können Sie mit testen is not None. Versuchen Sie das folgende Beispiel:

import argparse as ap

def main():
    parser = ap.ArgumentParser(description="My Script")
    parser.add_argument("--myArg")
    args, leftovers = parser.parse_known_args()

    if args.myArg is not None:
        print "myArg has been set (value is %s)" % args.myArg

Die Tests "ist keine" und "ist nicht keine" funktionieren genau so, wie ich es möchte und erwarte. Vielen Dank.
Madeleine P. Vincent

39
Leider funktioniert es nicht, dann hat das Argument seinen defaultWert definiert.
kcpr

6
Wenn Sie einen Wert festlegen möchten, defaultkönnen Sie dennoch nargs='?'einen constWert festlegen und angeben , wie in den Dokumenten beschrieben . Wenn das Argument fehlt, defaultwird es verwendet, wenn das Argument ohne Wert angegeben wird, constwird es verwendet, andernfalls wird der angegebene Wert verwendet. Mit nur defaultund nargs='?', wird defaultverwendet, wenn nicht gegeben, Nonewenn w / o - Wert angegeben, andernfalls den angegebenen Wert.
Ioannis Filippidis

@IoannisFilippidis, wenn Sie dieses Argument verwenden action= "store_true"oder action="store_const", const="yourconst"nicht, um einen anderen Wert zu speichern. Dies funktioniert nicht, wenn Standardeinstellungen verwendet werden. In meinen eigenen habe ich alle Standardeinstellungen von argparser entfernt und alle in einer anderen Funktion behandelt, def defaults():in der ich ConfigParser, ArgumentParser und Standardwerte in der gewünschten Reihenfolge
mische

@ erm3nda Ich habe das Setzen eines nicht erwähnt action. Die Antwort verwendet kein action. Es wird dokumentiert, dass sich die von Ihnen erwähnten Aktionen auf eine bestimmte Weise verhalten (wie Sie beobachtet haben). Es ist jedoch nicht erforderlich, eine Aktion zu definieren.
Ioannis Filippidis

37

Wie @Honza bemerkt, is Noneist ein guter Test. Dies ist die Standardeinstellung default, und der Benutzer kann Ihnen keine Zeichenfolge geben, die sie dupliziert.

Sie können eine andere angeben default='mydefaultvalueund diese testen. Was aber, wenn der Benutzer diese Zeichenfolge angibt? Zählt das als Einstellung oder nicht?

Sie können auch angeben default=argparse.SUPPRESS. Wenn der Benutzer das Argument dann nicht verwendet, wird es nicht im argsNamespace angezeigt. Aber das könnte komplizierter sein:

args.foo # raises an AttributeError
hasattr(args, 'foo')  # returns False
getattr(args, 'foo', 'other') # returns 'other'

Intern parserführt der eine Liste von seen_actionsund verwendet sie für 'erforderliche' und 'gegenseitig ausschließende' Tests. Aber es steht Ihnen außerhalb von nicht zur Verfügung parse_args.


22

Ich denke, die Option default=argparse.SUPPRESSist am sinnvollsten. Anstatt zu prüfen, ob das Argument ist not None, prüft man dann, ob das Argument inder resultierende Namespace ist.

Beispiel:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--foo", default=argparse.SUPPRESS)
ns = parser.parse_args()

print("Parsed arguments: {}".format(ns))
print("foo in namespace?: {}".format("foo" in ns))

Verwendung:

$ python argparse_test.py --foo 1
Parsed arguments: Namespace(foo='1')
foo in namespace?: True
Argument wird nicht geliefert:
$ python argparse_test.py
Parsed arguments: Namespace()
foo in namespace?: False

Dies funktioniert bei mir unter Python 3.7.5 (Anaconda) nicht. Ich bekomme das Ergebnistestfoo.py: error: argument --foo: expected one argument
Mike Wise

@MikeWise Wenn Sie --fooohne Wert verwenden möchten (dh 1in meinem Beispiel), müssen Sie dies nargs=0in der add_argumentFunktion angeben .
Erasmus Cedernaes

Ich habe Ihren Code einfach kopiert und eingefügt, wie in der Antwort angegeben. Vielleicht solltest du es bearbeiten? Am Ende habe ich stattdessen die action='store_true'unten stehende Antwort in meinem eigentlichen Code verwendet.
Mike Wise

@ MikeWise hast du das Skript ausgeführt als python argparse_test.py --foo 1?
Erasmus Cedernaes

11

Sie können ein optional übergebenes Flag mit store_trueund store_falseArgumentaktionsoptionen überprüfen :

import argparse

argparser = argparse.ArgumentParser()
argparser.add_argument('-flag', dest='flag_exists', action='store_true')

print argparser.parse_args([])
# Namespace(flag_exists=False)
print argparser.parse_args(['-flag'])
# Namespace(flag_exists=True)

Auf diese Weise müssen Sie sich keine Gedanken über die Überprüfung durch Bedingungen machen is not None. Sie suchen einfach nach Trueoder False. Weitere Informationen zu diesen Optionen finden Sie in den Dokumenten hier


1
Dies lässt sich nicht lösen, um zu wissen, ob ein Argument mit einem Wert festgelegt ist oder nicht. Das Hauptproblem hierbei ist zu wissen, ob der args-Wert von defaul = "" stammt oder vom Benutzer angegeben wird.
m3nda

5

Wenn Ihr Argument positionell ist (dh es hat kein "-" oder "-" Präfix, nur das Argument, normalerweise einen Dateinamen), können Sie den Parameter nargs verwenden , um dies zu tun:

parser = argparse.ArgumentParser(description='Foo is a program that does things')
parser.add_argument('filename', nargs='?')
args = parser.parse_args()

if args.filename is not None:
    print('The file name is {}'.format(args.filename))
else:
    print('Oh well ; No args, no problems')

3

Hier ist meine Lösung, um zu sehen, ob ich eine Argparse-Variable verwende

import argparse

ap = argparse.ArgumentParser()
ap.add_argument("-1", "--first", required=True)
ap.add_argument("-2", "--second", required=True)
ap.add_argument("-3", "--third", required=False) 
# Combine all arguments into a list called args
args = vars(ap.parse_args())
if args["third"] is not None:
# do something

Dies könnte einen besseren Einblick in die obige Antwort geben, die ich für mein Programm verwendet und angepasst habe.


0

Um den Kommentar von @ kcpr zu der (derzeit akzeptierten) Antwort von @Honza Osobne zu adressieren

Leider funktioniert es nicht, dann hat das Argument seinen Standardwert definiert.

Man kann zuerst überprüfen, ob das Argument bereitgestellt wurde, indem man es mit dem NamespaceObjekt abd vergleicht, das die default=argparse.SUPPRESSOption bereitstellt (siehe Antworten von @ hpaulj und @Erasmus Cedernaes und dieses python3-Dokument ). Wenn es nicht angegeben wurde, setzt man es auf einen Standardwert.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--infile', default=argparse.SUPPRESS)
args = parser.parse_args()
if 'infile' in args: 
    # the argument is in the namespace, it's been provided by the user
    # set it to what has been provided
    theinfile = args.infile
    print('argument \'--infile\' was given, set to {}'.format(theinfile))
else:
    # the argument isn't in the namespace
    # set it to a default value
    theinfile = 'your_default.txt'
    print('argument \'--infile\' was not given, set to default {}'.format(theinfile))

Verwendung

$ python3 testargparse_so.py
argument '--infile' was not given, set to default your_default.txt

$ python3 testargparse_so.py --infile user_file.txt
argument '--infile' was given, set to user_file.txt

0

Sehr einfach, nachdem die Variable args durch 'args = parser.parse_args ()' definiert wurde, enthält sie auch alle Daten der Variablen der Teilmenge args. Um zu überprüfen, ob eine Variable gesetzt ist oder nicht, wird angenommen, dass 'action = "store_true" verwendet wird ...

if args.argument_name:
   # do something
else:
   # do something else
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.