【问题标题】:argparse and custom Actions - code path not obviousargparse 和自定义操作 - 代码路径不明显
【发布时间】:2018-12-06 20:52:41
【问题描述】:

我使用 argparse 来消化文本命令,而不是尝试滚动我自己的自定义解析器,但代码路径并不明显。考虑以下几点:

import argparse

##class ReadAction(argparse.Action):
##    def __init__(self, option_strings, dest, nargs=None, **kwargs):
##        if nargs is not None:
##            raise ValueError("nargs not allowed")
##        super(ReadAction, self).__init__(option_strings, dest, **kwargs)
##    def __call__(self, parser, namespace, values, option_strings=None):
##        print("Read a file")
##        setattr(namespace, self.dest, values)

class ExitAction(argparse.Action):
    def __init__(self, option_strings, dest, nargs=None, **kwargs):
        if nargs is not None:
            raise ValueError("nargs not allowed")
        super(ExitAction, self).__init__(option_strings, dest, **kwargs)
    def __call__(self, parser, namespace, values, option_strings=None):
        print("Exiting the program")
        setattr(namespace, self.dest, values)

def setup_parser(parser):
##    parser.add_argument('read', help='Reads in a file', action=ReadAction)
    parser.add_argument('exit', help='Exit command', action=ExitAction)

def run():
    parser = argparse.ArgumentParser()
    setup_parser(parser)
    while True:
        raw_input = input("Command >>>").split(' ')
        args = parser.parse_args(raw_input)
        print(args)
    print('Good bye')

if __name__ == '__main__':
    run()

如果我按原样运行它,我会得到预期的输出:

Command >>>exit
Exiting the program
Namespace(exit='exit')

但如果我取出 cmets 并再次运行,我会得到这种意外行为:

Command >>>exit
Read a file
usage: prog.py [-h] read exit
prog.py: error: the following arguments are required: exit

有没有人理解这个代码路径?就像没有调用 __call__ 方法(​​讽刺)。

【问题讨论】:

    标签: python argparse


    【解决方案1】:

    readexit 两个参数都需要一个字符串。

    解析第一个字符串会导致调用ReadAction.__call__,并在args 命名空间中设置一个值。如果您只提供一个字符串,则解析器会引发错误,因为尚未提供 exit 参数。如果您提供了两个字符串,则第二个字符串将提供给 ExitAction.__call__

    如果解析器完成且没有错误,您的代码将继续 while 循环,而不会退出。摆脱该循环的唯一方法是让解析器引发错误。

    遇到此错误,解析器会打印用法和消息,然后调用sys.exit(2)-h 命令将导致调用 -h 操作。这会打印帮助并调用sys.exit(2)

    虽然argparse 可用于解析input 字符串,但它不是为该任务而设计的。通常它会解析sys.argv[1:]。也就是说,ipythonmagic 命令经常使用argparse 来解析参数,其行为很像 sys shell 命令。

    argparse 不根据值分配位置参数 - 它严格根据位置分配它们。如果您同时定义readexit,则第一个字符串将转到read,而不管其值如何,第二个字符串将转到exit。 (见我最近的回答:https://stackoverflow.com/a/53605878/901925

    标记的 (optionals) 是根据值分配的。但是要使用那些你必须给出类似的命令

    --read foo --exit bar

    【讨论】:

    • 我可能会回来并使用可选参数进行调查,看看是否适合我的目的,但时间很短,所以我必须构建自己的简单解析器。谢谢!
    【解决方案2】:

    您没有将命令绑定到文字字符串 readexitargparse 不是这样工作的。相反,您正在定义一个解析器,它接受两个任意单词,并将第一个绑定到read,第二个绑定到exit。无论您输入什么单个字,您的注释代码都会退出,而不仅仅是exit。如果没有 cmets,解析器需要两个单词,并且当您只提供一个单词时会引发错误。

    如果您打算以这种方式(ab)使用argparse,我建议您阅读文档中的子命令。

    【讨论】:

    • 好的,这是有道理的。最好是在有限的时间内为我想做的事情而建立自己。谢谢!
    猜你喜欢
    • 2021-11-07
    • 2017-09-05
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    相关资源
    最近更新 更多