gpt4 book ai didi

python - 默认子命令,或不使用 argparse 处理子命令

转载 作者:IT老高 更新时间:2023-10-28 22:04:54 25 4
gpt4 key购买 nike

我怎样才能有一个默认 sub-command , 或使用 argparse 处理未给出子命令的情况?

import argparse

a = argparse.ArgumentParser()
b = a.add_subparsers()
b.add_parser('hi')
a.parse_args()

在这里,我希望选择一个命令,或者仅基于下一个最高级别的解析器(在本例中为顶级解析器)处理的参数。

joiner@X:~/src> python3 default_subcommand.pyusage: default_subcommand.py [-h] {hi} ...default_subcommand.py: error: too few arguments

最佳答案

在 Python 3.2(和 2.7)上,您会收到该错误,但在 3.3 和 3.4 上不会(无响应)。因此,在 3.3/3.4 上,您可以测试 parsed_args做个空Namespace .

更通用的解决方案是添加一个方法 set_default_subparser() (取自 ruamel.std.argparse 包)并在 parse_args() 之前调用该方法:

import argparse
import sys

def set_default_subparser(self, name, args=None, positional_args=0):
"""default subparser selection. Call after setup, just before parse_args()
name: is the name of the subparser to call by default
args: if set is the argument list handed to parse_args()

, tested with 2.7, 3.2, 3.3, 3.4
it works with 2.6 assuming argparse is installed
"""
subparser_found = False
for arg in sys.argv[1:]:
if arg in ['-h', '--help']: # global help if no subparser
break
else:
for x in self._subparsers._actions:
if not isinstance(x, argparse._SubParsersAction):
continue
for sp_name in x._name_parser_map.keys():
if sp_name in sys.argv[1:]:
subparser_found = True
if not subparser_found:
# insert default in last position before global positional
# arguments, this implies no global options are specified after
# first positional argument
if args is None:
sys.argv.insert(len(sys.argv) - positional_args, name)
else:
args.insert(len(args) - positional_args, name)

argparse.ArgumentParser.set_default_subparser = set_default_subparser

def do_hi():
print('inside hi')

a = argparse.ArgumentParser()
b = a.add_subparsers()
sp = b.add_parser('hi')
sp.set_defaults(func=do_hi)

a.set_default_subparser('hi')
parsed_args = a.parse_args()

if hasattr(parsed_args, 'func'):
parsed_args.func()

这适用于 2.6(如果 argparse 是从 PyPI 安装的)、2.7、3.2、3.3、3.4。并允许您两者兼而有之

python3 default_subcommand.py

python3 default_subcommand.py hi

同样的效果。

允许为默认选择一个新的子解析器,而不是现有的一个。

代码的第一个版本允许将先前定义的子解析器之一设置为默认子解析器。以下修改允许添加一个新的默认子解析器,然后可以使用它来专门处理用户没有选择子解析器的情况(代码中标记了不同的行)

def set_default_subparser(self, name, args=None, positional_args=0):
"""default subparser selection. Call after setup, just before parse_args()
name: is the name of the subparser to call by default
args: if set is the argument list handed to parse_args()

, tested with 2.7, 3.2, 3.3, 3.4
it works with 2.6 assuming argparse is installed
"""
subparser_found = False
existing_default = False # check if default parser previously defined
for arg in sys.argv[1:]:
if arg in ['-h', '--help']: # global help if no subparser
break
else:
for x in self._subparsers._actions:
if not isinstance(x, argparse._SubParsersAction):
continue
for sp_name in x._name_parser_map.keys():
if sp_name in sys.argv[1:]:
subparser_found = True
if sp_name == name: # check existance of default parser
existing_default = True
if not subparser_found:
# If the default subparser is not among the existing ones,
# create a new parser.
# As this is called just before 'parse_args', the default
# parser created here will not pollute the help output.

if not existing_default:
for x in self._subparsers._actions:
if not isinstance(x, argparse._SubParsersAction):
continue
x.add_parser(name)
break # this works OK, but should I check further?

# insert default in last position before global positional
# arguments, this implies no global options are specified after
# first positional argument
if args is None:
sys.argv.insert(len(sys.argv) - positional_args, name)
else:
args.insert(len(args) - positional_args, name)

argparse.ArgumentParser.set_default_subparser = set_default_subparser

a = argparse.ArgumentParser()
b = a.add_subparsers(dest ='cmd')
sp = b.add_parser('hi')
sp2 = b.add_parser('hai')

a.set_default_subparser('hey')
parsed_args = a.parse_args()

print(parsed_args)

“默认”选项仍然不会显示在帮助中:

python test_parser.py -h
usage: test_parser.py [-h] {hi,hai} ...

positional arguments:
{hi,hai}

optional arguments:
-h, --help show this help message and exit

但是,现在可以区分并分别处理调用提供的子解析器之一和在未提供参数时调用默认子解析器:

$ python test_parser.py hi
Namespace(cmd='hi')
$ python test_parser.py
Namespace(cmd='hey')

关于python - 默认子命令,或不使用 argparse 处理子命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6365601/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com