且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用 argparse 中的子命令创建解析器,自定义位置参数

更新时间:2023-02-16 18:07:10

所以三个示例调用是:

python reader.py some.txt 
python reader.py new another.txt
python reader.py edit some.txt

处理这些问题的最简单方法是使用一个可选"位置和一个必需的.

The easiest way to handle these is with one 'optional' positional, and one required one.

parser = ArgumentParser...
parser.add_argument('-v','--verbose', ...)
parser.add_argument('cmd', nargs='?', default='open', choices=['open','edit','new'])
parser.add_argument('filename')

对于您的 3 个样本,它应该产生如下结果:

For your 3 samples, it should produce something like:

namespace(cmd='open', filename='some.txt')
namespace(cmd='new', filename='another.txt')
namespace(cmd='edit', filename='some.txt')

cmd 是一个可选的位置参数.如果缺少,则将一个字符串分配给filenamecmd 获取其default.这样做比尝试将 subparsers 设为可选更容易.

cmd is an optional positional argument. If it is missing, the one string will be allocated to filename, and cmd gets its default. It's easier to do this than trying make a subparsers optional.

至于您当前的解析器:

parent_parser = argparse.ArgumentParser(description="Read text files.")
parent_parser.add_argument('filename', help='TXT file', type=file, nargs='+')

我不推荐使用 type=file.***使用 FileType 或默认字符串(它允许您稍后在 with context 中打开文件).

I would not recommend using type=file. Better to use FileType or the default string (which lets you open the file in a with context later).

至于 nargs='+',您真的要为 filename 分配 1 或更多 个字符串吗?或者您是否考虑过?",即 0 或 1,即使其成为可选?

As to the nargs='+', do you really want to allocate 1 or more strings to filename? Or were you thinking of '?', which would be 0 or 1, i.e. making it optional?

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 位置,它接受可变数量的值,和一个子解析器参数(一个需要 newedit 的位置)可能有问题.

Mixing this filename positional which accepts a variable number of values, with a subparsers argument (a positional that expects either new or edit) could be a problem.

我希望 'python reader.py some.txt' 反对缺少 subparser 命令.'python reader.py new another.txt' 将尝试将 new 分配给 filenameanother.txt子解析器,并引发错误.

I expect 'python reader.py some.txt' to object that the subparser command is missing. 'python reader.py new another.txt' will try to allocate new to filename, and another.txt to subparser, and raise an error.

***在所有 3 种情况下都使用 subparsers 命令:

It would be better to expect a subparsers command in all 3 cases:

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'、'new'、'edit',都需要一个'文件名'.

Each of commands, 'open','new','edit', expects a 'filename'.

试图避免使用 open 命令会带来更多的困难.

Trying to avoid the use of an open command is going to create more difficulties than it's worth.

(最新的 argparse 中有一个错误/功能使子解析器成为可选的,但您不应该在不真正了解问题的情况下利用它.)

(There is a bug/feature in the latest argparse that makes subparsers optional, but you shouldn't take advantage of that without really knowing the issues.)

与:

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 新的自定义字符串

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

openedit 将使用不同的 open 模式.

open and edit would use different open modes.

请注意,在 Py3 中,不需要 subparsers.也就是说,如果未提供其中一个子命令,则不会引发错误.这是对早期版本的无意更改.

Beware that in Py3, subparsers are not required. That is, if one of the subcommands is not provided, it won't raise an error. That's an inadvertent change from early versions.

带有所需子解析器的 Argparse