【问题标题】:How do I restrict passed variable to specific values in python?如何将传递的变量限制为python中的特定值?
【发布时间】:2019-05-04 04:38:25
【问题描述】:

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

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

【问题讨论】:

  • 所以您想将输入限制为 30 个预定义值,而不必告诉解释器这些值是什么?
  • 你能分享你的价值观吗?
  • type in add_argument 是一个函数 - 它应该接受一个字符串,根据需要进行检查和转换。 choices 可以是字符串列表。 Argparse 进行in 测试。 help 中无法很好地显示一长串选项。

标签: python parameter-passing argparse predefined-variables


【解决方案1】:

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

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

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


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

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

那么你可以使用var in options

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

options |= {7, 42, False}

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


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

【讨论】:

    【解决方案2】:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      • 2018-08-30
      • 2022-01-19
      • 2019-08-10
      相关资源
      最近更新 更多