具有依赖项和冲突的python argparse子命令
我想使用argparse构建一个带有子命令的工具。可能的语法可能是 /tool.py下载--从1234开始--间隔60 /tool.py下载--构建1432 /tool.py clean--数字10 所以我想使用argparse来实现:具有依赖项和冲突的python argparse子命令,python,argparse,Python,Argparse,我想使用argparse构建一个带有子命令的工具。可能的语法可能是 /tool.py下载--从1234开始--间隔60 /tool.py下载--构建1432 /tool.py clean--数字10 所以我想使用argparse来实现: 确保始终同时使用“--from”和“--interval” 确保“--build”从未与其他参数一起使用 但是我没有找到一种方法将“--from”和“--internal”配对到一个组,然后使该组与“--build”相互排斥 下面是我当前的代码,它只使'--fr
parser = argparse.ArgumentParser(description='A Tool')
subparsers = parser.add_subparsers(help='sub-command help')
#create the parser for the 'download' command
download_parser = subparsers.add_parser('download', help='download help')
download_parser.add_argument('--interval', dest='interval', type=int,help='interval help')
group = download_parser.add_mutually_exclusive_group()
group.add_argument('--from',type=int, help='from help')
group.add_argument('--build', type=int, help='interval help')
比如说,
/tool.py下载--来自1234
不应被允许,因为“--from”必须与“--interval”一起使用。但是我的代码默默地接受它
及
/tool.py下载--间隔1234--构建5678
不应被允许,因为“--build”不能与其他参数一起使用。但我的代码也接受它
如有任何建议,将不胜感激。谢谢。您可以使用:
import argparse
import sys
class VerifyNoBuild(argparse.Action):
def __call__(self, parser, args, values, option_string=None):
# print 'No: {n} {v} {o}'.format(n=args, v=values, o=option_string)
if args.build is not None:
parser.error(
'--build should not be used with --from or --interval')
setattr(args, self.dest, values)
class VerifyOnlyBuild(argparse.Action):
def __call__(self, parser, args, values, option_string=None):
# print 'Only: {n} {v} {o}'.format(n=args, v=values, o=option_string)
if getattr(args, 'from') is not None:
parser.error('--from should not be used with --build')
if getattr(args, 'interval') is not None:
parser.error('--interval should not be used with --build')
setattr(args, self.dest, values)
parser = argparse.ArgumentParser(description='A Tool')
subparsers = parser.add_subparsers(help='sub-command help')
# create the parser for the 'download' command
download_parser = subparsers.add_parser('download', help='download help')
download_parser.add_argument('--interval',
type=int, help='interval help',
action=VerifyNoBuild)
download_parser.add_argument('--from',
type=int, action=VerifyNoBuild)
download_parser.add_argument('--build',
type=int, action=VerifyOnlyBuild)
args = parser.parse_args('download --from 1234 --interval 60'.split())
print(args)
# Namespace(build=None, from=1234, interval=60)
args = parser.parse_args('download --build 1432'.split())
print(args)
# Namespace(build=1432, from=None, interval=None)
args = parser.parse_args('download --build 1432 --from 1234'.split())
print(args)
# usage: test.py download [-h] [--interval INTERVAL] [--from FROM] [--build BUILD]
# test.py download: error: --build should not be used with --from or --interval
args = parser.parse_args('download --build 1432 --interval 60'.split())
print(args)
# usage: test.py download [-h] [--interval INTERVAL] [--from FROM] [--build BUILD]
# test.py download: error: --build should not be used with --from or --interval
但实际上,我认为这更简短:
def parse_options():
parser = argparse.ArgumentParser(description='A Tool')
subparsers = parser.add_subparsers(help='sub-command help')
#create the parser for the 'download' command
download_parser = subparsers.add_parser('download', help='download help')
download_parser.add_argument('--interval', type=int, help='interval help')
download_parser.add_argument('--from', type=int)
download_parser.add_argument('--build', type=int)
opt=parser.parse_args()
from_interval=[getattr(opt,key) is not None for key in ('from','interval')]
if opt.build is not None:
if any(from_interval):
sys.exit('error!')
elif not all(from_interval):
sys.exit('error!')
return opt
你有代码,但到底是什么不起作用?举一个错误行为的例子,并解释你的预期。我添加了两个错误行为的例子。谢谢你的建议。自定义操作非常有用。我修改了您的代码以确保--from和--interval始终一起使用。它工作得很好。谢谢!:)@兰蒂:啊,是的,我忘了那种情况。您是否在
VerifyNoBuild
类中验证了该条件?如果是这样,请发布您的解决方案好吗?我想看看是怎么做到的。我已经修改了替代解决方案来处理这种情况。很抱歉响应太晚。实际上我的代码很简单。正如您所说,我修改了VerifyNoBuild类,在调用setattr()之前添加了以下行:if(args.begin为None)或(args.interval为None):sys.exit('--from和--interval必须一起使用')
@Landy:您确定这样做有效吗?VerifyNoBuild
操作通常被调用两次(当同时提供了--from
和--interval
时)。第一次调用VerifyNoBuild.\uuu调用时,getattr(args,'from')
或getattr(args,'interval')
将是None
。这将导致调用sys.exit
,即使提供了两个参数。您是对的。我只是测试了不可接受的论点,没有尝试可接受的论点(((