使用Python的“argh”时,如何收集未指定的命令行选项?

时间:2017-10-23 07:16:11

标签: python parameter-passing command-line-arguments argh

使用Python CLI库argh我想编写一个包装工具。这个包装工具假设读取两个选项-a-b并将所有其他选项传递给一个函数(然后通过subprocess调用包装的UNIX工具和剩余选项)。

我已尝试使用dispatch参数skip_unknown_args

def wrapper(a=True, b=False):
    print("Enter wrapper")
    # 1. process a and b 
    # 2. call_unix_tool(left-over-args)

if __name__ == '__main__':
    parser = argh.ArghParser()
    argh.set_default_command(parser, wrapper)
    argh.dispatch(parser, skip_unknown_args=True)

但是,程序在遇到未知选项时仍会退出,并且根据需要不会输入函数wrapper。另外,我不知道存储未知/跳过的参数的位置,以便我可以将它们传递给UNIX工具。

如何通过跳过的参数告诉argh进入wrapper

2 个答案:

答案 0 :(得分:1)

我相信这是一个错误。

initContent时,这里skip_unknown_args=True是一个元组,带有一个名称空间对象和剩余的args:

namespace_obj

底层(Pdb) p namespace_obj (ArghNamespace(_functions_stack=[<function wrapper at 0x105cb5e18>], a=False, b=True), ['-c']) 期望一个一元:

_get_function_from_namespace_obj

我查了its coressponding issue and unittest,不知道作者期望的合法性是什么,也在那里发表评论。

为什么不直接使用154 function = _get_function_from_namespace_obj(namespace_obj) ... 191 if isinstance(namespace_obj, ArghNamespace):

答案 1 :(得分:0)

您无法使用skip_unknown_args=True执行此操作,因为as @georgexsh pointed out argh库似乎没有明智地使用该选项。但是,您可以提供自己的解析器类,将未知参数注入普通命名空间:

class ArghParserWithUnknownArgs(argh.ArghParser):
    def parse_args(self, args=None, namespace=None):
        namespace = namespace or ArghNamespace()
        (namespace_obj, unknown_args) = super(ArghParserWithUnknownArgs, self).parse_known_args(args=args, namespace=namespace)
        namespace_obj.__dict__['unknown_args'] = unknown_args
        return namespace_obj

注意这个班级&#39; parse_args方法调用ArgParser&#39; parse_ known _args方法!

定义此类后,您可以按照以下方式编写包装器代码:

def wrapper(a=True, b=False, unknown_args={}):
    print("a = %s, b = %s" % (a,b))
    print("unknown_args = %s" % unknown_args)

if __name__ == '__main__':
    parser = ArghParserWithUnknownArgs()
    argh.set_default_command(parser, wrapper)
    argh.dispatch(parser)

在主函数wrapper中,您可以通过参数unknown_args访问所有未知参数,并将其传递给您的子进程命令

ps:为了使帮助信息整洁,用

装饰wrapper
@argh.arg('--unknown_args', help=argparse.SUPPRESS)

附录:我创建了一个增强版的解析器,并将其编译成一个即用型模块。在Github上找到它。