Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python argparse和optparse的子命令替代项_Python_Argparse_Optparse - Fatal编程技术网

Python argparse和optparse的子命令替代项

Python argparse和optparse的子命令替代项,python,argparse,optparse,Python,Argparse,Optparse,子命令的argparse/optparse是否有直观的替代方法?它们都不好——要么是疯狂的配置,要么是疯狂的输出 真实世界示例(,不需要): 通缉: >>> parser = cmdline.Parser( ... tplheader='Usage: tool [command] [options]', ... tplcommandhead='Available commands:', ... tplfooter='Use \"tool help\" to get

子命令的argparse/optparse是否有直观的替代方法?它们都不好——要么是疯狂的配置,要么是疯狂的输出

真实世界示例(,不需要):

通缉:

>>> parser = cmdline.Parser(
...   tplheader='Usage: tool [command] [options]',
...   tplcommandhead='Available commands:',
...   tplfooter='Use \"tool help\" to get full list of supported commands.')
>>> parser.add('foo', help='foo.')
>>> parser.add('bar', help='bar.')
>>> parser.parse(['-h'])
Usage: tool [command] [options]
Available commands:

  foo        foo.
  bar        bar.

Use "tool help" to get full list of supported commands.

更新:我接受提供命令验证和解析示例的答案,该示例提供的帮助消息与上一个代码片段完全相同。

听起来像是您在寻找的

以下是主页上演示文稿的一个片段

具有多个命令的潜在模块化应用程序:

当然,它是有效的:

网站上的帮助信息略为删节。下面是它为我实际输出的内容(
argh
0.26.1)


我不确定我是否理解你所描述的有什么不对。 不过,我使用了一些稍有不同的方法:

parser = argparse.ArgumentParser(description='My description')
parser.add_argument('-i', '--input', type=str, required=True, help='Inputfile')
parser.add_argument('-o', '--output', type=str, required=False, help='Output file')
args = parser.parse_args()
input_filename = args.input
if not args.output:
    output_filename = input_filename
else:
    output_filename = args.output

这个得奖了吗?:)

自定义参数 罗伯·肯尼迪有更好的定制

In [158]: parser=argparse.ArgumentParser(usage='tool [command] [options]',
  description= "Available commands:\n\n   foo    foo.\n   bar    bar.\n",
  epilog= 'Use "tool help" to get full list of supported commands',
  formatter_class=argparse.RawDescriptionHelpFormatter, add_help=False)

In [159]: parser.print_help()
usage: tool [command] [options]

Available commands:

   foo    foo.
   bar    bar.

Use "tool help" to get full list of supported commands
我所做的是使用可用参数自定义
帮助

替代API和/或解析器? 但是您的其他行,
parse.add()
表明您不喜欢定义“命令”的
argparse
方法。您可以向解析器中添加一些使用这种更紧凑语法的方法,但仍然会调用现有的
subparser
机制

但也许你想用你自己的语法分析方案来代替整个语法分析方案。例如,期望第一个参数是“command”的参数。其他“位置”呢?谁或什么来处理“选项”

您是否意识到
argparse
子parser方案是建立在更基本的
选项
位置
解析方案之上的。
parser.add_subparsers
命令是
add_参数
的一种特殊形式。
子parsers
对象是一个位置参数,带有一个特殊的动作类
{foo,bar}
实际上是您为此参数定义的
选项
值(子命令的名称或别名)的列表。子命令本身就是解析器

自定义前端命令分析器 如果
sys.argv[1]
项始终是
命令名,则可以设置如下内容:

if sys.argv[1:]:
    cmd = sys.argv[1]
    rest = sys.argv[2:]
    parser = parser_dict.get(cmd, None)
    if parser:
        args = parser.parse_args(rest)
else:
    print_default_help()
其中,
parser\u dict
是将
cmd
字符串与定义的解析器匹配的字典。实际上,这只是一个前端,它捕获第一个参数字符串,并将其余参数的处理分派给其他定义的解析器。它们可以是
argparse
optparse
和自定义解析器的组合。如果前端处理的都是第一个“命令”字符串,那么它就不必太花哨了

print\u default\u help
只不过是
parser\u dict
的漂亮打印

经过进一步思考,我意识到
argparse
subparsers对象的
sp.choices
属性就是这样一个字典——命令字符串作为键,解析器作为值

自定义格式\u帮助方法 这里有两个自定义帮助格式化程序

一个仅从
解析器
获取
程序
选项
操作
的简单方法<代码>子解析器。_choices_actions是包含各个子解析器的帮助和别名信息的对象列表

def simple_help(parser, subparsers):
    # format a help message with just the subparser choices
    usage = "Usage: %s command [options]"%parser.prog
    desc = "Available commands:\n"
    epilog = '\nUse "%s help" to get full list of supported commands.'%parser.prog
    choices = fmt_choices(subparsers._choices_actions)
    astr = [usage]
    astr.append(desc)
    astr.extend(choices)
    astr.append(epilog)
    return '\n'.join(astr)

def fmt_choices(choices):
    # format names and help in 2 columns
    x = max(len(k.metavar) for k in choices)
    fmt = '   {:<%s}   {}'%x
    astr = []
    for k in choices:
        # k.metavar lists aliases as well
        astr.append(fmt.format(k.dest, k.help))
    return astr
可以用不同的方式调用这些函数。这两种方法都可以替换
解析器的
格式帮助
方法,因此可以由
-h
选项以及
解析器生成。打印帮助()

或者可以包含一个
帮助
子命令。这将与
epilog
消息相匹配<代码>-h
仍然会产生全面、丑陋的帮助

sp3 = sp.add_parser('help')  # help='optional help message'
和测试
args

if args.cmd in ['help']:
    print(simple_help(parser, sp))
    # print(special_help(parser))

另一个选项是在
parser.parser_args
之前选中
sys.argv
,如果列表不够长,或者包含
help
字符串,则调用help函数。这大致就是
Ipython
绕过常规的
argparse
帮助所做的工作。

只需稍微更改argparse代码,就可以非常接近请求的输出:

  • 通过将
    usage
    参数指定为
    ArgumentParser
    来设置用法文本
  • 省略
    说明
    帮助
    参数以
    添加子参数
  • 标题
    参数更改为
    可用子命令
  • 使用
    metavar
    参数覆盖难看的
    {foo,bar}
    文本
  • 使用
    add\u parser
    中提供的
    help
    参数
  • 这是成品:

    import argparse
    parser = argparse.ArgumentParser(usage='tool [command] [options]')
    subparsers = parser.add_subparsers(title='Available commands', metavar='')
    subparsers.add_parser('foo', help='foo.')
    subparsers.add_parser('bar', help='bar.')
    parser.parse_args(['-h'])
    
    该代码打印了以下内容:

    usage: tool [command] [options] optional arguments: -h, --help show this help message and exit Available commands: foo foo. bar bar. 用法:工具[命令][选项] 可选参数: -h、 --帮助显示此帮助消息并退出 可用命令: 福福。 酒吧。 你应该看一看。在文档中,单击

    • 是无限制的惰性组合
    • 完全遵循Unix命令行约定
    • 支持直接从环境变量加载值
    • 支持提示自定义值
    • 是完全可嵌套和可组合的
    • 在Python2和Python3中的工作原理相同
    • 支持开箱即用的文件处理
    • 附带有用的常用帮助程序(获取终端尺寸、ANSI颜色、获取直接键盘输入、清除屏幕、查找配置路径、启动应用程序和编辑器等)
    使用decorator创建参数和选项非常直观。您可以通过如下所示创建组来创建子命令

    import click                                                    
    
    
    @click.command()                                                
    @click.option('--count', default=1, help='number of greetings') 
    @click.argument('name')                                         
    def hello(count, name):                                         
        for i in range(count):                                      
            print(f"{i}. Hello {name}")                             
    
    @click.group()                                                  
    def cli():                                                      
        pass                                                        
    
    @cli.command()                                                  
    def initdb():                                                   
        click.echo('Initialized the database')                      
    
    @cli.command()                                                  
    def dropdb():                                                   
        click.echo('Dropped the database')                          
    
    if __name__ == "__main__":                                      
        cli() 
    
    此代码的输出为:

    $ python click-example.py --help
    Usage: click-example.py [OPTIONS] COMMAND [ARGS]...
    
    Options:
      --help  Show this message and exit.
    
    Commands:
      dropdb
      initdb
    

    关于
    /app.py-h
    ?用网站的副本更新了答案,但实际上,检查其余的链接。tin上的内容完全没有帮助。不过,它的功能要好得多。是在
    argparse之上构建的另一个解析器if args.cmd in ['help']:
        print(simple_help(parser, sp))
        # print(special_help(parser))
    
    import argparse
    parser = argparse.ArgumentParser(usage='tool [command] [options]')
    subparsers = parser.add_subparsers(title='Available commands', metavar='')
    subparsers.add_parser('foo', help='foo.')
    subparsers.add_parser('bar', help='bar.')
    parser.parse_args(['-h'])
    
    usage: tool [command] [options] optional arguments: -h, --help show this help message and exit Available commands: foo foo. bar bar.
    import click                                                    
    
    
    @click.command()                                                
    @click.option('--count', default=1, help='number of greetings') 
    @click.argument('name')                                         
    def hello(count, name):                                         
        for i in range(count):                                      
            print(f"{i}. Hello {name}")                             
    
    @click.group()                                                  
    def cli():                                                      
        pass                                                        
    
    @cli.command()                                                  
    def initdb():                                                   
        click.echo('Initialized the database')                      
    
    @cli.command()                                                  
    def dropdb():                                                   
        click.echo('Dropped the database')                          
    
    if __name__ == "__main__":                                      
        cli() 
    
    $ python click-example.py --help
    Usage: click-example.py [OPTIONS] COMMAND [ARGS]...
    
    Options:
      --help  Show this message and exit.
    
    Commands:
      dropdb
      initdb