How do I set an Argparse argument's default value to a positional argument's value?
Question: I have a python script that sends a GET request. It uses Argparse to take
three arguments:

  1. **Address** : where to send the GET request
  2. **Host** : the host to declare in the GET request
  3. **Resource** : which resource is being requested

An example usage might be:

`$ python get.py 198.252.206.16 stackoverflow.com /questions/ask`

In most cases, however, only the host and the resource need to be given as the
host will resolve to the address:

    
    
     $ host -t a stackoverflow.com
     stackoverflow.com has address 198.252.206.16
    

So desired usage might be:

    
    
    $ python get.py stackoverflow.com /questions/ask
    

How do I set up Argparse so that the default value of the Address argument is
the value of the Host argument?

* * *

I've been asked to show the code that currently parses the arguments. Here it
is:

    
    
    import argparse
    
    parser = argparse.ArgumentParser(description=
             'Send a GET request and obtain the HTTP response header and/or body.')
    
    parser.add_argument("-v", "--verbose",
                        help="Turn on verbose mode.",
                        action="store_true")
    parser.add_argument("-p", "--port",
                        type=int,
                        default=80,
                        help="Which port to use when sending the GET request."
    parser.add_argument("address",
                        help="Where to send the GET request to.")
    parser.add_argument("host",
                        help="Which Host to declare in the GET request.")   
    parser.add_argument("resource",
                        help="Which resource to request.")
    
    parser.parse_args()
    


Answer: If you are trying to achieve the behaviour you described using ONLY positional
arguments you can use a list argument (nargs) like this:

    
    
    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument("args", nargs="+")
    parsed = parser.parse_args()
    args = parsed.args
    if len(args) == 3:
        ip, host, address = args
        print ip, host, address
    elif len(args) == 2:
        ip, host, address = args[0], args[0], args[1]
        print ip, host, address
    else:
        print "Invalid args"
    

But not only is this hacky you also lose the benefits argparse provides (you
have to manually verify the arguments). I recommend you use optional
arguments. Perhaps like this:

    
    
    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument("-host", required=True)
    parser.add_argument("-res", required=True)
    parser.add_argument("-ip", required=False)
    args = parser.parse_args()
    
    ip = args.ip if args.ip else args.host
    print args.host, args.res, ip
    

And execute it like this:

    
    
    python2.7 test.py -host hello -res world
    

