-1

我正在编写脚本,通过argparse模块使用 CLI 传递值。我想知道这是否可以限制变量保存预定义的值,以避免用户错误。这不是类型限制,值由字母和数字组成,当然我可以写一个if块,但我有大约 30 个预定义值,所以写类似

if var is value1 or var is value2 ... or var is value30:
  pass
else:
    print("oops, your value does not fit")

会很痛苦。这样做的正确方法是什么?

4

2 回答 2

2

不要单独检查每个项目的相等性,而是检查它是否在一组有效项目中。

if var in {'foo', 'bar', 'etc.'}:

另外,不要使用is检查字符串相等性。使用==. Python 中的字符串可能包含与另一个字符串相同的内容,但不是同一个对象。编译器应该从文字中实习(即重用)字符串,但这只是一种优化。运行时生成的字符串应该生成新对象。不过,有一些方法可以手动实习。


对于像这样的很长的选项列表,我可能会将它们从字符串中拆分出来以制作集合,例如

options = set("""
spam
eggs
sausage
bacon
ham
""".split())

然后你可以使用var in options.

您甚至可以将其他可散列类型合并到集合中。

options |= {7, 42, False}

尽管无论如何用户输入都会以字符串开始。


另一个需要考虑的选项是re模块。正则表达式可以匹配大量相关字符串,有时非常紧凑。这取决于您要允许的选项类型。

于 2018-12-02T20:38:04.707 回答
1

choices

In [214]: parser = argparse.ArgumentParser()
In [215]: parser.add_argument('--foo', choices=['one','two','three','four']);

公认:

In [216]: parser.parse_args('--foo one'.split())
Out[216]: Namespace(foo='one')

被拒绝:

In [217]: parser.parse_args('--foo five'.split())
usage: ipython3 [-h] [--foo {one,two,three,four}]
ipython3: error: argument --foo: invalid choice: 'five' (choose from 'one', 'two', 'three', 'four')

帮助:

In [218]: parser.parse_args('-h'.split())
usage: ipython3 [-h] [--foo {one,two,three,four}]

optional arguments:
  -h, --help            show this help message and exit
  --foo {one,two,three,four}

如果我定义了 a metavar,帮助将是

usage: ipython3 [-h] [--foo CHOICES]

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

或者如果选项太长,定义一个type函数:

In [222]: def mychoices(astr):
     ...:     if astr in ['one','two','three','four']:
     ...:         return astr
     ...:     else:
     ...:         raise argparse.ArgumentTypeError('Wrong choice')

In [223]: parser = argparse.ArgumentParser()
In [224]: parser.add_argument('--foo', type=mychoices);

In [225]: parser.parse_args('--foo one'.split())
Out[225]: Namespace(foo='one')

In [226]: parser.parse_args('--foo five'.split())
usage: ipython3 [-h] [--foo FOO]
ipython3: error: argument --foo: Wrong choice

In [227]: parser.parse_args('-h'.split())
usage: ipython3 [-h] [--foo FOO]

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO
于 2018-12-03T07:02:27.407 回答