所以三个示例调用是:
python reader.py some.txt
python reader.py new another.txt
python reader.py edit some.txt
处理这些问题的最简单方法是使用一个“可选”位置和一个必需的位置。
parser = ArgumentParser...
parser.add_argument('-v','--verbose', ...)
parser.add_argument('cmd', nargs='?', default='open', choices=['open','edit','new'])
parser.add_argument('filename')
对于您的 3 个样本,它应该产生如下内容:
namespace(cmd='open', filename='some.txt')
namespace(cmd='new', filename='another.txt')
namespace(cmd='edit', filename='some.txt')
cmd 是一个可选的位置参数。如果缺少,则将一个字符串分配给filename,而cmd 将得到它的default。这样做比尝试将subparsers 设为可选更容易。
至于你当前的解析器:
parent_parser = argparse.ArgumentParser(description="Read text files.")
parent_parser.add_argument('filename', help='TXT file', type=file, nargs='+')
我不建议使用type=file。最好使用FileType 或默认字符串(让您稍后在with context 中打开文件)。
至于nargs='+',你真的要把1 or more字符串分配给filename吗?或者您是否在考虑“?”,即0 or 1,即使其成为可选?
parent_parser.add_argument('--verbose', '-v', action='store_true',
help="Verbosity on")
child_parser = parent_parser.add_subparsers(title="subcommand",
help="Subcommand help")
new_file_command = child_parser.add_parser('new', help="New text file")
edit_file_command = child_parser.add_parser('edit', help="Edit existing text file")
将这个接受可变数量值的filename 位置与子解析器参数(预期new 或edit 的位置)混合可能会出现问题。
我希望'python reader.py some.txt' 反对缺少子解析器命令。 'python reader.py new another.txt' 将尝试将new 分配给filename,并将another.txt 分配给子解析器,并引发错误。
最好在所有 3 种情况下都使用 subparsers 命令:
parent_parser = argparse.ArgumentParser(description="Read text files.")
parent_parser.add_argument('--verbose', '-v', action='store_true',
help="Verbosity on")
child_parser = parent_parser.add_subparsers(title="subcommand",
help="Subcommand help", dest='cmd')
open_file_command = child_parser.add_parser('open', help="Open text file")
open_file_command.add_argument('filename', help='TXT file')
new_file_command = child_parser.add_parser('new', help="New text file")
new_file_command.add_argument('filename', help='TXT file')
edit_file_command = child_parser.add_parser('edit', help="Edit existing text file")
edit_file_command.add_argument('filename', help='TXT file')
每个命令,“打开”、“新建”、“编辑”,都需要一个“文件名”。
试图避免使用open 命令会带来更多的困难。
(最新的 argparse 中有一个错误/功能使子解析器成为可选的,但您不应该在不真正了解问题的情况下利用它。)
与:
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--verbose')
parser.add_argument('cmd', nargs='?', default='open',
choices=['open', 'edit', 'new'])
parser.add_argument('filename', nargs='+')
我希望reader.py new customstring 给予
namespace(cmd='new', filename=[customstring])
可以用作:
if args.cmd=='new':
with open(args.filename[0] + '.txt', 'w') as f:
# do something with the newly created file
open 和 edit 将使用不同的 open 模式。
请注意,在 Py3 中,subparsers 不是必需的。也就是说,如果未提供其中一个子命令,则不会引发错误。这是早期版本的无意更改。
Argparse with required subparser