简体   繁体   中英

Checking if sys.argv[x] is defined

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]

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

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.

Another way I haven't seen listed yet is to set your sentinel value ahead of time. This method takes advantage of Python's lazy evaluation, in which you don't always have to provide an else statement. Example:

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

Or if you're going syntax CRAZY you could use Python's ternary operator :

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

I use this - it never fails:

startingpoint = 'blah'
if sys.argv[1:]:
   startingpoint = sys.argv[1]

It's an ordinary Python list. The exception that you would catch for this is IndexError, but you're better off just checking the length instead.

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

Pretty close to what the originator was trying to do. Here is a function I use:

def get_arg(index):
    try:
        sys.argv[index]
    except IndexError:
        return ''
    else:
        return sys.argv[index]

So a usage would be something like:

if __name__ == "__main__":
    banner(get_arg(1),get_arg(2))

A solution working with map built-in fonction !

arg_names = ['command' ,'operation', 'parameter']
args = map(None, arg_names, sys.argv)
args = {k:v for (k,v) in args}

Then you just have to call your parameters like this:

if args['operation'] == "division":
    if not args['parameter']:
        ...
    if args['parameter'] == "euclidian":
        ...

You can simply append the value of argv[1] to argv and then check if argv[1] doesn't equal the string you inputted Example:

from sys import argv
argv.append('SomeString')
if argv[1]!="SomeString":
            print(argv[1])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM