Checking if sys.argv[x] is defined


Question

What would be the best way to check if a variable was passed along for the script:

try:
    sys.argv[1]
except NameError:
    startingpoint = 'blah'
else:
    startingpoint = sys.argv[1]
1
77
7/31/2016 10:26:15 AM

Accepted Answer

In the end, the difference between try, except and testing len(sys.argv) isn't all that significant. They're both a bit hackish compared to argparse.

This occurs to me, though -- as a sort of low-budget argparse:

arg_names = ['command', 'x', 'y', 'operation', 'option']
args = dict(zip(arg_names, sys.argv))

You could even use it to generate a namedtuple with values that default to None -- all in four lines!

Arg_list = collections.namedtuple('Arg_list', arg_names)
args = Arg_list(*(args.get(arg, None) for arg in arg_names))

In case you're not familiar with namedtuple, it's just a tuple that acts like an object, allowing you to access its values using tup.attribute syntax instead of tup[0] syntax.

So the first line creates a new namedtuple type with values for each of the values in arg_names. The second line passes the values from the args dictionary, using get to return a default value when the given argument name doesn't have an associated value in the dictionary.

54
11/3/2017 1:12:36 PM

Check the length of sys.argv:

if len(sys.argv) > 1:
    blah = sys.argv[1]
else:
    blah = 'blah'

Some people prefer the exception-based approach you've suggested (eg, try: blah = sys.argv[1]; except IndexError: blah = 'blah'), but I don't like it as much because it doesn't “scale” nearly as nicely (eg, when you want to accept two or three arguments) and it can potentially hide errors (eg, if you used blah = foo(sys.argv[1]), but foo(...) raised an IndexError, that IndexError would be ignored).


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon