1

以下功能和用法示例准确说明了我对这种用法的需求:

test([{True | False}])

>>> def test(arg=True):
...     if arg:
...         print "argument is true"
...     else:
...         print "argument is false"
...
>>> test()
argument is true
>>> test(True)
argument is true
>>> test(False)
argument is false
>>> test(1)
argument is true
>>> test(0)
argument is false
>>> test("foo")
argument is true
>>> test("")
argument is false
>>>

现在我想要完全相同的用法和行为,但使用命令行解析,即使用这种用法:

python test [{True | False}]

所以我想弄清楚如何用这样的东西来做:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-arg",
    help="I want the usage to be [{True | False}] (defaults to True)")
arg = parser.parse_args().arg

if arg:
    print "argument is true"
else:
    print "argument is false"

但我无法弄清楚。我尝试了各种选项和选项组合,其中action="store_true", default=True, choices=[True, False]type=bool但没有任何效果如我所愿,例如:

$ python test.py -h
usage: test.py [-h] [-arg ARG]

optional arguments:
  -h, --help  show this help message and exit
  -arg ARG    I want the usage to be [{True | False}] (defaults to True)

$ python test.py
argument is true

$ python test.py True
usage: test.py [-h] [-arg ARG]
test.py: error: unrecognized arguments: True

etc.

谢谢你的帮助。

4

3 回答 3

2

Find or write a function that parses strings like 'True', 'False'. For example http://www.noah.org/wiki/Python_notes#Parse_Boolean_strings

def ParseBoolean (b):
    # ...
    if len(b) < 1:
        raise ValueError ('Cannot parse empty string into boolean.')
    b = b[0].lower()
    if b == 't' or b == 'y' or b == '1':
        return True
    if b == 'f' or b == 'n' or b == '0':
        return False
    raise ValueError ('Cannot parse string into boolean.')

Think of this as the boolean equivalent of int() and float() Then just use it as the argument type

p.add_argument('foo',type=ParseBoolean)

bool() doesn't work because the only string it interprets as False is ''.

于 2013-07-28T05:17:17.633 回答
1

如果您给参数一个以“-”开头的名称,它将成为一个标志参数。正如您从“用法”中看到的那样,它除了被调用test.py -arg True

如果您不想放在-arg参数本身之前,则应将其命名为arg,因此它将成为位置参数。

参考:http ://docs.python.org/dev/library/argparse.html#name-or-flags

默认情况下,它会将参数转换为字符串。所以if arg:不起作用。结果将与您调用if "foo":.

如果您希望能够在命令行上键入TrueFalse,您可能希望将它们保留为字符串并使用if arg == "True". argparse 支持布尔参数,但据我所知,它们只支持以下形式:test.py --arg导致 arg=true,而只会test.py导致 arg=false

参考:http ://docs.python.org/dev/library/argparse.html#type

于 2013-07-25T12:46:29.663 回答
1

感谢 varesa 让我找到了这个解决方案:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("arg",
    nargs="?",
    default="True",
    help="I want the usage to be [{True | False}] (defaults to True)")
arg = parser.parse_args().arg

if arg == "True":
    arg = True
elif arg == "False":
    arg = False
else:
    try:
        arg = float(arg)
        if arg == 0.:
            arg = True
        else:
            arg = False
    except:
        if len(arg) > 0:
            arg = True
        else:
            arg = False

if arg:
    print "argument is true"
else:
    print "argument is false"

However it seems to me quite complicated. Am I dumb (I am new to Python) or could there be a more simple, more straightforward, more elegant way of doing this? A way that would be close to the very straightforward way that a function handles it, as shown in the original posting.

于 2013-07-26T07:51:22.750 回答