带有可选参数的选项



>假设我有

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

我想在我的代码中区分:

  • --files未指定。
  • --files指定,但没有接受默认值的参数。
  • --files myfile,即--files使用自定义参数指定。

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

  • 不指定--files
  • 使用参数指定--files

所以我错过了:

  • 指定不带参数--files的选项。
  • 区分是否指定了--files,或者用户是否指定了--files 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成为真/假参数,并添加另一个参数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

相关内容

  • 没有找到相关文章

最新更新