如何将传递的变量限制为 python 中的特定值?

How do I restrict passed variable to specific values in python?

我正在编写脚本,通过 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")

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

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

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

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


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

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

那你可以用var in options.

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

options |= {7, 42, False}

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


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

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}

如果我定义了 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