argparse和自定义操作-代码路径不明显

时间:2018-12-06 20:52:41

标签: python argparse

我使用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')

但是,如果我删除注释并再次运行,则会出现此意外行为:

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

有人知道这样做的代码路径吗?就像没有调用__call__方法(讽刺)。

2 个答案:

答案 0 :(得分:0)

您没有将命令绑定到文字字符串readexit上; argparse的工作方式并非如此。相反,您正在定义一个解析器,该解析器使用两个任意单词,并将第一个绑定到read,第二个绑定到exit。无论您键入什么单个单词,您注释的代码都将退出,而不仅仅是exit。没有注释,解析器将期望两个单词,并且仅提供一个单词时会引发错误。

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

答案 1 :(得分:0)

自变量readexit都期望一个字符串。

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

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

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

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

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

已标记(optionals)是根据值分配的。但是要使用这些命令,您必须提供类似命令

  
    
      

-读取foo-退出栏