问题
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