且构网

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

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

更新时间:2023-02-16 17:48:42

因此,有三个示例调用:

So three sample calls are:

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是可选的位置参数.如果丢失,则将一个字符串分配给filename,而cmd获得其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 or more字符串吗?还是您在考虑'?',它是0 or 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位置变量与可变数量的值混合,并使用subparsers自变量(期望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分配给filename,将another.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'都需要一个'filename'.

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 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

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