문제

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
도움이 되었습니까?

해결책

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

다른 팁

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.

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>

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top