如何在 argparse 的位置参数中继承顶层选项

how to inherit toplevel options within positional arguments in argparse

我有一些代码想要实现,例如 git 选项处理。

import argparse

def get_options():
    parser = argparse.ArgumentParser(description='database maintance')
    parser.add_argument('--database', default = 'series' )

    subparsers = parser.add_subparsers(dest='operation', help='commands')
    list_parser = subparsers.add_parser('list', help='list')
    list_parser.add_argument('--tables', nargs='*', default=['all'], help="tables to list")

    repair_parser = subparsers.add_parser('repair', help='repair data')
    repair_parser.add_argument('date', help='Repair missing dates')

    delete_parser = subparsers.add_parser('delete', help='delete data')
    delete_parser.add_argument('table', nargs=1, default=argparse.SUPPRESS, help="table to delete date in")
    delete_parser.add_argument('--tables', nargs='*', default=[], help="additional tables to apply delete")

    opts = parser.parse_args()
    print(opts)
    return opts

if __name__ == '__main__':
    opts = get_options()

这段代码的问题在于,虽然你可以这样调用它。

$ ./maint.py list --tables t1 t2
Namespace(database='series', operation='list', tables=['t1', 't2'])

或者这样..

$ ./maint.py --database main list --tables t1 t2
Namespace(database='main', operation='list', tables=['t1', 't2'])

不能这样称呼..

$ ./maint.py list --tables t1 t2 --database main
usage: maint.py [-h] [--database DATABASE] {list,repair,delete} ...
maint.py: error: unrecognized arguments: --database main

为了让它工作,我必须将所有参数从顶层解析器添加到 sub_parsers。

list_parser.add_argument('--database', default = 'series' ) 
repair_parser.add_argument('--database', default = 'series' )
delete_parser.add_argument('--database', default = 'series' )

有没有更好的方法可以让所有 sub_parsers 调用顶层选项?

您可以在单独的解析器中定义 --database 选项,该选项通过 parents 选项传递给主解析器和所有子解析器。

db = argparse.ArgumentParser(add_help=False)
db.add_argument("--database", default='series')

parser = argparse.ArgumentParser(description='database maintance', <b>parents=[db]</b>)
subparsers = parser.add_subparsers(dest='operation', help='commands')
list_parser = subparsers.add_parser('list', <b>parents=[db],</b> help='list')
repair_parser = subparsers.add_parser('repair', <b>parents=[db],</b> help='repair data')
delete_parser = subparsers.add_parser('delete', <b>parents=[db],</b> help='delete data')

--database 可以在子命令之前或之后使用。