>假设我有
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
中的--files
和FNAME
的值来推断要执行的操作:
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