我有一个程序接受一个文件作为输入,有些工作与文件的内容,并将其推送到服务器。我想添加一个可选的命令行开关来指定程序的“干运行”,从而执行所有文件处理,但跳过写入服务器的操作。我使用argparse引入命令行参数,但我没有看到在参数之间执行“OR”函数的方法。这是我或多或少要寻找的......
允许的选项:
1)prog.py inputfile servername
2)prog.py inputfile -d
3)prog.py inputfile -d servername
Dissallowed:
1)prog.py输入文件
我想确保命令行上的服务器名称“OR”干运行标志。并且,如果两者都在那里......那也没关系。 (因此是OR而不是异或)。如果我使用required = true互斥,我可以获得异或;但是,我似乎无法弄清楚如何做到这两个可以存在的“或”。更复杂的是,服务器名称是位置参数,而干运行标志是可选参数,可以在命令行的任何位置。有没有人知道如何解决这个问题?
答案 0 :(得分:6)
这就是我要做的事情:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--dry-run', action='store_true')
parser.add_argument('input_file', type=argparse.FileType('r'))
parser.add_argument('servername', nargs='?')
args = parser.parse_args()
if args.servername is None and not args.dry_run:
parser.error("Option 'servername' is required when not in dry-run mode.")
print args
示例:
$ ./prog.py inputfile servername
Namespace(dry_run=False, input_file=<open file 'inputfile', mode 'r' at 0x283440>, servername='servername')
$ ./prog.py inputfile -d
Namespace(dry_run=True, input_file=<open file 'inputfile', mode 'r' at 0x2cf440>, servername=None)
$ ./prog.py -d inputfile servername
Namespace(dry_run=True, input_file=<open file 'inputfile', mode 'r' at 0x1f4440>, servername='servername')
$ ./prog.py inputfile
usage: prog.py [-h] [-d] input_file [servername]
prog.py: error: Option 'servername' is required when not in dry-run mode.
您也可以使用自定义操作执行此操作,它具有相同的效果:
class ServernameAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if values is None and not namespace.dry_run:
parser.error("Option 'servername' is required when not in dry-run mode.")
setattr(namespace, self.dest, values)
...
parser.add_argument('servername', nargs='?', action=ServernameAction)
...
答案 1 :(得分:3)
argparse
无法完成所有可能的验证组合,因此值得学习如何在事后添加自己的验证。例如:
parser = argparse.ArgumentParser(epilog='Either foo or bar (or both) must be specified.')
parser.add_argument('--foo', help='do something.')
parser.add_argument('--bar', help='do something else.')
args = vars(parser.parse_args())
if not args['foo'] and not args['bar']:
parser.error('Either foo or bar (or both) must be specified.')
答案 2 :(得分:0)
如果使用-d
时忽略服务器名称,请为其提供一个默认值,如果您尝试使用它肯定会导致错误(无论如何都需要验证它,对吗?):
p.add_argument("server", default=None)
如果给出了-d
,你可能不会同时验证或使用服务器名称,并且每件事都没问题。否则,您的代码在尝试验证时会捕获错误的服务器名称。