具有依赖关系和冲突的Python argparse子命令 [英] python argparse subcommand with dependency and conflict
本文介绍了具有依赖关系和冲突的Python argparse子命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想使用argparse构建一个包含子命令的工具。可能的语法可以是
/tool.py下载--从1234--间隔60
/tool.py下载--内部版本1432
/TOOL.PY CLEAN--数字10
所以我想使用argparse来实现:
- 确保‘--From’和‘--Interval’始终一起使用
- 确保‘--Build’从未与其他参数一起使用
但我没有找到一种方法将‘--from’和‘--Internal’配对到一个组,然后使该组与‘--Build’互斥。
下面是我当前的代码,它只是使‘--from’和‘--Build’是互斥的。既不要确保‘--from’和‘--Interval’放在一起,也不要确保‘--Interval’和‘--Build’是互斥的。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"一起使用。但我的代码以静默方式接受它。
和
不应允许/工具.py下载--间隔1234--内部版本5678
,因为‘--Build’不能与其他参数一起使用。但我的代码也接受它。
任何建议都将受到高度赞赏。谢谢。
推荐答案
您可以使用custom actions:
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
这篇关于具有依赖关系和冲突的Python argparse子命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文