带有可选参数的选项

Option with optional argument

假设我有

My program

Usage:
  myprog [options]

Options:
  -h, --help        Show this screen.
      --version     Show version.
      --files=<arg> Files. [default: foo.txt]

我想在我的代码中区分:

使用当前的文档字符串我可以

所以我失踪了:

您需要在主要用法字符串中指定 --files 参数。例如:

# dopt.py
from docopt import docopt

dstr = """My program

Usage:
  myprog [--files [FNAME]] [options]

Options:
  -h, --help        Show this screen.
      --version     Show version.
"""

if __name__ == '__main__':
    arguments = docopt(dstr)
    print(arguments)

这实际上使 --files 成为一个 true/false 参数,并添加了另一个参数 FNAME 来保存文件名。 用法:

$ python dopt.py
{'--files': False,
 '--help': False,
 '--version': False,
 'FNAME': None}

$ python dopt.py --files
{'--files': True,
 '--help': False,
 '--version': False,
 'FNAME': None}

$ python dopt.py --files abc.txt
{'--files': True,
 '--help': False,
 '--version': False,
 'FNAME': 'abc.txt'}

然后,您可以根据返回的 dict--filesFNAME 的值来推断要做什么:

if not arguments['--files']:
    print("Not using files")
elif not arguments['FNAME']:
    print("Using default file foo.txt")
else:
    print(f"Using file {arguments['FNAME']}")

要记住的一个陷阱:您还可以独立于 --files 指定 FNAME。所以这也有效,并且它可能会干扰其他参数,所以一定要彻底测试所有组合:

$ python dopt.py abc.txt
{'--files': False,
 '--help': False,
 '--version': False,
 'FNAME': 'abc.txt'}
Not using files

就个人而言,我更喜欢使用 argparse,因为它不那么含糊。它根据规定的参数构建文档字符串,而不是相反。

argparse 中,一个参数可以有一个默认值,您可以使用 nargs="?" 指定它可以接受零个或一个参数。然后,您可以指定一个 const="foo.txt" 值,如果没有给出值,参数将采用该值。例如:

# dopt.py
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--files", required=False, default=None, nargs="?", const="foo.txt")
p = parser.parse_args()
print(p)

和运行这个:

$ python dopt.py
Namespace(files=None)

$ python dopt.py --files
Namespace(files='foo.txt')

$ python dopt.py --files abc.txt
Namespace(files='abc.txt')

它甚至可以正确处理“没有 --files”的情况:

$ python dopt.py abc.txt
usage: dopt.py [-h] [--files [FILES]]
dopt.py: error: unrecognized arguments: abc.txt