0

我有两节课:

选项解析器
应用

存储在单独的文件中(option_parser.py 和 application.py)。前者定义了如何处理命令行输入。后者导入前者,读取用户输入,并进行请求。

如何调用在 application.py 的 Application 中定义的方法而不将其导入 option_parser.py 中(因为这会导致无限循环,因为 application.py 从 option_parser.py 导入 OptionParser)。如果我使用set_defaults(func=method_name),那么我被告知全局函数method_name未在该范围内定义。

我已经有一个解决方法,但它似乎并不正确:

if self.options.action == 'tags':
    self.list_tags()
elif self.options.action == 'branches':
    self.list_branches()

我试图在官方文档、谷歌和 SO 上找到答案 - 无济于事。

4

1 回答 1

0

我假设您正在使用文档set_defaults(func=method_name)中所示的子解析器argparse?这是调用函数的一种简单方法。它利用了在args命名空间中定义默认值和设置属性的灵活性。但是没有专门用于此功能的代码。

将函数与此类操作相关联通常是为每个子解析器处理不同操作的最简单方法。但是,如果需要检查被调用的子解析器的名称,add_subparsers() 调用的 dest 关键字参数将起作用:

第二句话是允许你使用

if self.options.action == 'tags'

在您的情况下set_defaults,这不是最简单的方法。

argparse主要是找出用户想要什么的一种方法。它并不意味着成为调度员。通常这是您的代码的责任。

我对其他argparse问题的印象是大多数时候程序员不使用这个set_defaults选项。对 SO 的搜索[argparse] set_default仅出现 37 个帖子(答案或问题)(相比之下,仅 argparse 标签的问题为 1.5K)。


这是一个工作脚本,它实现了我将set_defaults值传递给parser设置函数的想法。这是一个文件,但parser也可以导入该部分。

import argparse

def make_parser(defaults):
    parser = argparse.ArgumentParser()
    sp = parser.add_subparsers(dest='cmdstr')
    sp.required = True
    for key in defaults:
        spp = sp.add_parser(key)
        spp.set_defaults(cmd=defaults[key])
    return parser

def foo(args):
    print('foo')

def bar(args):
    print('bar')

if __name__=='__main__':
    dd = {'cmd1': foo, 'cmd2': bar}
    parser = make_parser(dd)
    args = parser.parse_args()
    print(args)
    args.cmd(args)

示例调用:

0930:~/mypy$ python3 stack42897689.py cmd1
Namespace(cmd=<function foo at 0xb70c2dac>, cmdstr='cmd1')
foo
0931:~/mypy$ python3 stack42897689.py cmd2
Namespace(cmd=<function bar at 0xb7145614>, cmdstr='cmd2')
bar

有了这本dd字典,我可以很容易地完成调度:

dd[args.cmdstr](None)

基本目标是将命令行字符串与函数调用配对。 set_defaults是一种在argparse. 但是像字典一样dd在 Python 代码中也被广泛使用。if/else陈述也是如此。

于 2017-03-20T07:25:00.683 回答