问题
I would like to check whether an optional argparse argument has been set by the user or not.
Can I safely check using isset?
Something like this:
if(isset(args.myArg)):
#do something
else:
#do something else
Does this work the same for float / int / string type arguments?
I could set a default parameter and check it (e.g., set myArg = -1, or "" for a string, or "NOT_SET"). However, the value I ultimately want to use is only calculated later in the script. So I would be setting it to -1 as a default, and then updating it to something else later. This seems a little clumsy in comparison with simply checking if the value was set by the user.
回答1:
I think that optional arguments (specified with --
) are initialized to None
if they are not supplied. So you can test with is not None
. Try the example below:
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
回答2:
As @Honza notes is None
is a good test. It's the default default
, and the user can't give you a string that duplicates it.
You can specify another default='mydefaultvalue
, and test for that. But what if the user specifies that string? Does that count as setting or not?
You can also specify default=argparse.SUPPRESS
. Then if the user does not use the argument, it will not appear in the args
namespace. But testing that might be more complicated:
args.foo # raises an AttributeError
hasattr(args, 'foo') # returns False
getattr(args, 'foo', 'other') # returns 'other'
Internally the parser
keeps a list of seen_actions
, and uses it for 'required' and 'mutually_exclusive' testing. But it isn't available to you out side of parse_args
.
回答3:
I think using the option default=argparse.SUPPRESS
makes most sense. Then, instead of checking if the argument is not None
, one checks if the argument is in
the resulting namespace.
Example:
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))
Usage:
$ python argparse_test.py --foo 1
Parsed arguments: Namespace(foo='1')
foo in namespace?: True
Argument is not supplied:
$ python argparse_test.py
Parsed arguments: Namespace()
foo in namespace?: False
回答4:
You can check an optionally passed flag with store_true
and store_false
argument action options:
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)
This way, you don't have to worry about checking by conditional is not None
. You simply check for True
or False
. Read more about these options in the docs here
回答5:
If your argument is positional (ie it doesn't have a "-" or a "--" prefix, just the argument, typically a file name) then you can use the nargs parameter to do this:
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')
回答6:
Here is my solution to see if I am using an argparse variable
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
This might give more insight to the above answer which I used and adapted to work for my program.
来源:https://stackoverflow.com/questions/30487767/check-if-argparse-optional-argument-is-set-or-not