Check if argparse optional argument is set or not

后端 未结 9 1517
臣服心动
臣服心动 2020-12-13 11:48

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:

<         


        
相关标签:
9条回答
  • 2020-12-13 12:05

    A custom action can handle this problem. And I found that it is not so complicated.

    is_set = set() #global set reference
    class IsStored(argparse.Action):
        def __call__(self, parser, namespace, values, option_string=None):
            is_set.add(self.dest) # save to global reference
            setattr(namespace, self.dest + '_set', True) # or you may inject directly to namespace
            setattr(namespace, self.dest, values) # implementation of store_action
            # You cannot inject directly to self.dest until you have a custom class
    
    
    parser.add_argument("--myarg", type=int, default=1, action=IsStored)
    params = parser.parse_args()
    print(params.myarg, 'myarg' in is_set)
    print(hasattr(params, 'myarg_set'))
    
    0 讨论(0)
  • 2020-12-13 12:07

    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')
    
    0 讨论(0)
  • 2020-12-13 12:08

    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.

    0 讨论(0)
  • 2020-12-13 12:09

    In order to address @kcpr's comment on the (currently accepted) answer by @Honza Osobne

    Unfortunately it doesn't work then the argument got it's default value defined.

    one can first check if the argument was provided by comparing it with the Namespace object abd providing the default=argparse.SUPPRESS option (see @hpaulj's and @Erasmus Cedernaes answers and this python3 doc) and if it hasn't been provided, then set it to a default value.

    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))
    

    Usage

    $ 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 讨论(0)
  • 2020-12-13 12:26

    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
    
    0 讨论(0)
  • 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
    
    0 讨论(0)
提交回复
热议问题