Brian C Brian C - 4 months ago 13
Python Question

Using argparse to overwrite variables depending on flags, use the default values if no args given (python)

I have a program that stores a few important variables as strings that are necessary for the program to operate properly:

DeviceNumber
,
IPAddress
, and
Port
. These variables are stored in a file, which is loaded by the program.

For debugging purposes, I would like to be able to quickly overwrite the files with command line arguments. The args would all be optional, and if not used then it just uses the variables taken out of the file.

I can do simple positional args using something like
DeviceNumber = sys.args[1]
, and only overwrite vars if the args are present, but this has the problem of not being able to handle if you enter the variables in the wrong order, or if you enter, say, the
IPAddress
and
Port
but not the
DeviceNumber
.

I have been reading through the pyDocs argparse Tutorial and documentation, but it does not seem terribly useful for what I need - it covers mandatory args, and optional flags, but does not seem to allow optional args that depend on a flag to denote their purpose. EDIT: Turns out it does, but the example is not very obvious, so I missed it. Similarly I have had trouble finding applicable questions here on SE.

In short, given a program like

#Default Names loaded from file
DeviceNumber = "2000"
IPAddress = "159.142.32.30"
Port = 80

#if command line args entered:
#overwrite default vars with arg corresponding to each one
#this probably involves argparse, but I don't know how

print "DNumber:"+DeviceNumber+" IP:"+IPAddress+" Port:"+Port


Some examples with different cmd line inputs/outputs would be:

All values are defaults

$ python myfile.py
DNumber:2000 IP:159.142.32.30 Port:80


All values are overridden

$ python myfile.py -n 1701 -ip 120.50.60.1 -p 3000
DNumber:1701 IP:120.50.60.1 Port:3000


Default
DNumber
, Override
IPAddress
+
Port
. Args were specified in different order.

$ python myfile.py -p 123 -ip 124.45.67.89
DNumber:2000 IP:124.45.67.89 Port:123


Default
DNumber
and
IPAddress
, Override
Port


$ python myfile.py -p 500
DNumber:2000 IP:159.142.32.30 Port:500


You get the idea...

for the syntax of the flag/args relationship, I am also not sure if there is a specific syntax python needs you to use (i.e.
-p 500
vs.
-p500
v
-p=500
)

Answer

There's a few ways to define default values for arguments specified by argparse. When adding arguments to your parser, you can specify a default value. Simply:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--port", dest="port", default=500,
    type=int, help="specify port")

args = parser.parse_args()
print "You've selected port: %d" % (args.port)

From the above example, it is trivial to extend to allow additional default functionality. Note that dest="port" is already by default due to the naming of the long argument --port. Like so:

parser.add_argument("-p", "--port", dest="port", default=None,
    type=int, help="specify port")

args = parser.parse_args()

if args.port is None:
    port = read_port_from_file()
    print "No optional port specified. Reading value from file." 

print "You've selected port: %d" % (args.port)