当我们使用add_parser时,函数构建并返回一个Parser对象,有没有办法用已经构建的Parser对象做同样的事情?
我想从类中构建对应于该对象的解析器。这样,从主脚本我可以调用一个返回类解析器的类方法,并将其添加到更高级别的解析器来构建最终的命令行。
我该怎么做? 谢谢, 杰罗姆
答案 0 :(得分:0)
我有点不清楚你需要什么,但可能是你创建subparsers时会发生什么的大纲。
p=argparse.ArgumentParser()
In [3]: sp=p.add_subparsers()
In [4]: sp
Out[4]: _SubParsersAction(option_strings=[], dest='==SUPPRESS==', nargs='A...',
const=None, default=None, type=None, choices=OrderedDict(), help=None,
metavar=None)
In [5]: sp._parser_class
Out[5]: argparse.ArgumentParser
In [7]: spp=sp.add_parser('cmd')
In [8]: spp
Out[8]: ArgumentParser(prog='ipython cmd', usage=None, description=None,
version=None, formatter_class=<class 'argparse.HelpFormatter'>,
conflict_handler='error',add_help=True)
sp
是位置Action
,它采用choices
(子分类名称)。它有hidden
属性_parser_class
,它是用于创建新子分析符的类。
Argparse: how to handle variable number of arguments (nargs='*')提高了改变_parser_class
以在子分析符中产生不同行为的可能性。 http://bugs.python.org/issue17204是一个相关的错误问题。
如果subparser只需要一个额外的方法(或现有的方法的自定义版本),有几种方法可以做到:
ArgumentParser
并使用子类作为解析器(如果解析器不使用新方法,则有效)。像Python: changing methods and attributes at runtime这样的线程讨论了改变实例方法的细节。
答案 1 :(得分:0)
您可以这样:通常定义您要使用的ArgumentParser
,然后将其传递给您的模块:
parser = argparse.ArgumentParser()
some_module.add_arguments(parser)
并在您的模块/对象中使用add_arguments()
方法:
def add_arguments(parser):
parser.add_argument(...)
答案 2 :(得分:0)
我喜欢在命令行工具Python脚本中使用它。
我有一个代表该工具的主类:
class MyToolCommandLineDriver(object):
@classmethod
def subcommand_map(cls):
# create a mapping of subcommand names to classes
return subcommand_map
@classmethod
def run(cls):
subcommand_map = cls.subcommand_map()
parser = argparse.ArgumentParser(description='Some Tool')
parser.add_argument('--some_global_option', help='Some Help')
subparsers = parser.add_subparsers(title='Subcommands', dest='subcommand_name')
for subcommand_name, subcommand_class in subcommand_map.items():
subparser = subparsers.add_parser(subcommand_name, help=subcommand_class.__doc__)
subcommand_class.configure_argument_parser(subparser)
if __name__ == "__main__":
MyToolCommandLineDriver.run()
每个subcommand_class
项都来自一个公共基类,并有机会配置自己的解析器:
class AbstractSubcommand(object):
@classmethod
def configure_argument_parser(cls, parser):
pass
class SubcommandFooBar(AbstractSubcommand):
@classmethod
def configure_argument_parser(cls, parser):
parser.add_argument('some_argument', nargs='+', help='Some help')
您可以在此处查看完整示例:https://github.com/liyanage/git-tools/blob/master/githelper/githelper.py
这是我制作的基于子命令的工具。此设置允许每个子命令定义其特定的参数,并且它还在顶层生成免费的有用用法消息:
$ githelper.py -h
usage: githelper.py [-h] [--root_path ROOT_PATH] [--verbose]
{status,reset-master-to-svn-branch,svn-conflicts,clone-externals,tree,svn-lineage,svn-diff,branch,each,svn-delete-resolve,svn-mergeinfo,svn-rebase,foo,checkout}
并为每个子命令:
$ githelper.py clone-externals -h
usage: githelper.py clone-externals [-h] svn_url checkout_directory
positional arguments:
svn_url The toplevel SVN repository to clone
checkout_directory The path to the sandbox directory to create