期望参数时的错误处理

sno*_*ind 5 python if-statement

第一次发帖,也是第一次尝试编码超过 99 瓶的东西......

我正在处理接受来自 cli 的参数(例如文本文件)的代码。预期用途是:

$:myfile.py input.txt

我已经让那部分顺利进行,但是如果没有提供参数,cli 会返回一个错误,我想提供一些错误响应,例如帮助列表或只是一个简单的“不 - 给我一个文件”

现在这里是前几行:

import sys
with open(sys.argv[1], 'r') as f:
    ifile = f.read()
    if len(sys.argv) == 1:
        empty = "Please give me something to do!"
        print empty
Run Code Online (Sandbox Code Playgroud)

如果我提供预期的参数,一切都很好,但如果没有提供参数,我会得到:

Traceback (most recent call last):
  File "myfile.py", line 3, in <module>
    with open(sys.argv[1], 'r') as f:
IndexError: list index out of range
Run Code Online (Sandbox Code Playgroud)

假设我只想在不满足条件的情况下打印变量“Empty”……我该怎么做才能解决这个问题。

编辑:在使用 argparse 尝试以下建议之一后,我得到了更好的结果,但我注意到 argparse 抛出了一个我不期望的字符。现在的代码是:

   def main(filename):
    # do something with filename
    print('your filename is %s' % filename)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='my program help')
    parser.add_argument('-f', help='specify file path')
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我希望看到 -h 和 -f 作为选项,但我在描述中看到了一个额外的 F。

my program help

optional arguments:
  -h, --help  show this help message and exit
  -f F        specify macro file path
Run Code Online (Sandbox Code Playgroud)

你能告诉我如何摆脱这个额外的 F。我尝试了一些东西,但它要么出现,要么在运行时出错。

Shm*_*ikA 3

用于argparse解析 cli 输入参数:

您的案例的示例代码:

import argparse


def main(filename):
    # do something with filename
    print('your filename is %s' % filename)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='my program help')
    parser.add_argument('filename', help='your desired filename')

    args = parser.parse_args()
    main(args.filename)
Run Code Online (Sandbox Code Playgroud)

从终端运行,不带参数,我们得到:

$ python ans_argparse.py
usage: ans_argparse.py [-h] filename
ans_argparse.py: error: the following arguments are required: filename
Run Code Online (Sandbox Code Playgroud)

带参数运行:

$ python ans_argparse.py 'myfile.txt'
your filename is 'myfile.txt'
Run Code Online (Sandbox Code Playgroud)

创建自定义解析器可能需要时间并且不是那么简单。 argparse有很多功能并且嵌入到 stdlib 中,因此更喜欢使用它。

另一个例子

我通常创建parse_args()函数,因此测试它或在外部调用它__main__更容易:

import sys
import argparse


def main(filename):
    # do something with filename
    print('your filename is %s' % filename)


def parse_args(args_lst):
    parser = argparse.ArgumentParser(description='my program help')
    parser.add_argument('filename', help='your desired filename')
    return parser.parse_args(args_lst)


if __name__ == '__main__':
    args = parse_args(sys.argv[1:])                 
    main(args.filename)
Run Code Online (Sandbox Code Playgroud)

你可以这样称呼它:

args = parse_args(['another_filename.txt'])
Run Code Online (Sandbox Code Playgroud)

更新

使用metavar可选参数更改帮助中变量的显示名称。我鼓励您阅读文档argparse以获取更多示例和用例

像这样:

parser.add_argument('-f', metavar='FILENAME', required=True, 
                    help='the file path for this program')
Run Code Online (Sandbox Code Playgroud)

输出python myprog.py --help

optional arguments:
  -h, --help   show this help message and exit
  -f FILENAME  the file path for this program
Run Code Online (Sandbox Code Playgroud)

注意:不要忘记required=True参数,这样你会收到一条错误消息argparse