【问题标题】:When does argparse not complain about this missing argument?argparse 什么时候不抱怨这个缺失的论点?
【发布时间】:2014-08-12 22:39:09
【问题描述】:

这个问题可能有一个明显的答案,但我已经看了一段时间没有弄清楚。这是一些使用 argparse 的旧 Python 代码。我最近没有使用 argparse,所以我可能忘记了一些细微差别。

#test.py

def load_crossval_dataset(args):
    schema, samplenum, permuted, search = args.schema, args.samplenum, args.permuted, args.search

    print "schema", schema
    print "samplenum", samplenum
    print "permuted", permuted
    print "search", search

import argparse
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
subparsers = parser.add_subparsers()

# create the parser for the "crossval" command                                                                                                                 
parser_crossval = subparsers.add_parser('crossval', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser_crossval.add_argument('schema', help='name of schema')
parser_crossval.add_argument("-n", "--samplenum", action="store", type=int, dest="samplenum", help="number of samples to do crossvalidation on")
parser_crossval.add_argument("-p", "--permuted", action="store_true", dest="permuted", help="permuted dataset", default=False)
parser_crossval.add_argument("-s", "--search", action="store_true", dest="search", help="model search", default=False)
parser_crossval.set_defaults(func=load_crossval_dataset)

args = parser.parse_args()
args.func(args)

让我们调用它:

python test.py

usage: test.py [-h] {crossval} ...
test.py: error: too few arguments

现在

python test.py crossval -h

usage: test.py crossval [-h] [-n SAMPLENUM] [-p] [-s] schema

positional arguments:
  schema                name of schema

optional arguments:
  -h, --help            show this help message and exit
  -n SAMPLENUM, --samplenum SAMPLENUM
                        number of samples to do crossvalidation on (default: None)
  -p, --permuted        permuted dataset (default: False)
  -s, --search          model search (default: False)

现在

python test.py crossval -n 1 -s True                                                                                                                         

schema True
samplenum 1
permuted False
search True

问题:为什么 argparse 不抱怨缺少 schema 参数,为什么将它设置为 True

【问题讨论】:

  • 我敢打赌args 的值会有所不同。 search 是布尔值 Trueschema 是字符串 'True'

标签: python argparse


【解决方案1】:

乍一看,-s 选项是布尔值 - 所以它的存在意味着 True 并且不需要参数。因此,当您说 python test.py crossval -n 1 -s True 时,True 会被解析为架构参数,因为 -s 开关不需要值。

这实际上可以从帮助文本中的用法字符串中收集到:

usage: test.py crossval [-h] [-n SAMPLENUM] [-p] [-s] schema

[-s] 表示它是一个空选项,与 -n 不同,它被列为 [-n SAMPLENUM],因为它需要一个参数 (SAMPLENUM)。

编辑

Python 2.7 Documentation for argparse 中说明了此行为,我推断这是您在示例中使用的版本,因为您使用的是语句形式而不是 print 的函数形式。引用第 15.4.3.2 节:

'store_true' 和 'store_false' - 这些是 'store_const' 的特殊情况,分别用于存储值 True 和 False。此外,它们分别创建了 False 和 True 的默认值。

【讨论】:

  • 是的,这是正确的答案。我想我对它是如何工作的记忆变得模糊了。文档中是否提到“它的存在意味着真实并且不需要论证”,如果是这样,你能向我指出(引用它)吗?谢谢。
  • 谢谢@minuteman3。但是,这并没有证明标志 -s 等的存在等同于将值设置为 True,在我看来,这是缺少的部分。
  • 也许我只是习惯了这种行为,因此在阅读文本时有偏见。您说得对,argparse 文档确实可以改进。这些天我个人更喜欢使用github.com/docopt/docopt
【解决方案2】:

-s 选项不带参数(store_conststore_truestore_false 操作不带参数 - 这可能会在文档中进行说明)。所以在python test.py crossval -n 1 -s True中,参数Truecrossval的位置参数,而不是-s的参数;因此它是schema 的值。

python test.py crossval -n 1 -s 正确地抱怨test.py crossval 缺少参数。

【讨论】:

  • 是的,看过docs.python.org/dev/library/argparse.html 之后,我没有看到任何地方表明布尔选项的存在意味着 True 和不存在的 False。虽然这是很自然的,而且大概读者应该推断出来,但如果明确说明就好了。
  • 来自文档:'store_true' and 'store_false' - These store the values True and False respectively. These are special cases of 'store_const'。还有很多使用store_true的例子。
  • argparse 建立在 optparse 的传统基础上,store_true 操作描述为:docs.python.org/2/library/…
  • @hpaulj 是的,但要注意they aren't fully compatible
猜你喜欢
  • 1970-01-01
  • 2016-05-06
  • 1970-01-01
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多