gpt4 book ai didi

具有依赖性和冲突的python argparse子命令

转载 作者:太空狗 更新时间:2023-10-29 21:47:45 26 4
gpt4 key购买 nike

我想使用 argparse 来构建一个带有子命令的工具。可能的语法是

/tool.py download --from 1234 --interval 60

/tool.py download --build 1432

/tool.py clean --numbers 10

所以我想用argparse来实现:

  1. 确保“--from”和“--interval”始终一起使用
  2. 确保“--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 download --from 1234

不应被允许,因为“--from”必须与“--interval”一起使用。但我的代码会默默地接受它。

/tool.py download --interval 1234 --build 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子命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5165415/

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