0

Normally I run this script fro the command line with one argument: python myscript.py argument

But when this argument is lacking, I want the error message to be shown:

usage: myscript.py [file ...]

Script:

import sys from lxml import etree filename = sys.argv[1] tree = etree.parse(filename) def f1(): ... def main(): if len(sys.argv) < 2: print 'usage: extract.py [file ...]' sys.exit(1) else: f1() 

Before I had this working, I could the error message in case there is no argument, but now it stopped working, I don't see why... I only get this message when I run the script without the argument from the command line:

Traceback (most recent call last): File "myscript.py", line 14, in <module> filename = sys.argv[1] IndexError: list index out of range 

3 Answers 3

3

The line filename = sys.argv[1] runs first. Your len() test is not reached.

Move setting the filename and tree into the main() function, and don't use globals here:

def f1(tree): ... def main(): if len(sys.argv) < 2: print 'usage: extract.py [file ...]' sys.exit(1) filename = sys.argv[1] tree = etree.parse(filename) f1(tree) if __name__ == '__main__': main() 
Sign up to request clarification or add additional context in comments.

Comments

1

As Martijn says, sys.argv[1] gets referenced before you test len().

I prefer to move the tests into the calling clause instead of main, like so:

import sys from lxml import etree def f1(tree): pass def main(filename): tree = etree.parse(filename) f1(tree) if __name__=="__main__": if len(sys.argv) == 2: main(sys.argv[1]) else: print 'usage: extract.py [file ...]' sys.exit(1) 

I feel this provides a more logical division of responsibilities in the code.

Comments

1

rather than doing all this why not use argparse module from python. If the argument is not provided it will automatically print the usage statement as below

import argparse parser = argparse.ArgumentParser() parser.add_argument('file', type=argparse.FileType('r')) args = parser.parse_args() print(args.file) 

type=argparse.FileType('r') argument is not necessary but it is better to use.

'r' represents and checks whether the file is readable or exists.

Similarly you can use 'w' to check if file that you are passing is writable.

Output:

$> python progargs.py

usage: progargs.py [-h] file

progargs.py: error: too few arguments

$> python progargs.py testanotherprog.py

'testanotherprog.py', mode 'r' at 0x7fe8ee422270>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.