在 argparse 中使用子命令创建解析器,自定义位置参数
Create parser with subcommands in argparse, customize positional argument(s)
我是这个模块的新手,所以请多多包涵。我有以下代码:
reader.py
import argparse
parent_parser = argparse.ArgumentParser(description="Read text files.")
parent_parser.add_argument('filename', help='TXT file', type=file, nargs='+')
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")
args = parent_parser.parse_args()
我想要实现的可能不是解析器和 unix 命令行实用程序工作方式的标准方式。如果那是真的,请纠正我,因为我想要标准化的应用程序。
这就是我要实现的目标:
- 如果你 运行 像这样带有位置参数的裸脚本:
python reader.py some.txt
我希望能够解析它并将它传递给读取文本文件的函数,当然我也想接受可选的 arg verbose
- 如果你 运行 子命令 'new' (
new_file_command
),我不想要求位置参数 filename
,相反我想传递一个字符串并像这样创建新的文本文件:python reader.py new another.txt
- 如果你 运行 子命令 'edit' (
edit_file_command
) 我想在路径中传递现有文件并检查它(就像你在 [=18] 中使用 type=int
=]) 然后可能将其传递给打开编辑器的函数,如下所示:python reader.py edit some.txt
同样,我不确定这是否是命令行 apps/scripts 的行为方式。我阅读了文档并查看了示例,但我仍然不清楚子解析器是如何工作的。我试着查看 Click 模块,但在我看来这更复杂。
感谢任何帮助。谢谢!
所以三个示例调用是:
python reader.py some.txt
python reader.py new another.txt
python reader.py edit some.txt
处理这些问题的最简单方法是使用一个 'optional' 位置,一个需要一个。
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
位置与 subparsers 参数(期望 new
或 edit
的位置)混合可能是个问题。
我希望 'python reader.py some.txt'
反对缺少 subparser 命令。 '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'、'new'、'edit' 都需要一个 'filename'.
试图避免使用 open
命令会造成比其价值更多的困难。
(最新的 argparse 中有一个 bug/feature 使子解析器可选,但您不应该在不真正了解问题的情况下利用它。)
有:
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
我是这个模块的新手,所以请多多包涵。我有以下代码:
reader.py
import argparse
parent_parser = argparse.ArgumentParser(description="Read text files.")
parent_parser.add_argument('filename', help='TXT file', type=file, nargs='+')
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")
args = parent_parser.parse_args()
我想要实现的可能不是解析器和 unix 命令行实用程序工作方式的标准方式。如果那是真的,请纠正我,因为我想要标准化的应用程序。
这就是我要实现的目标:
- 如果你 运行 像这样带有位置参数的裸脚本:
python reader.py some.txt
我希望能够解析它并将它传递给读取文本文件的函数,当然我也想接受可选的 argverbose
- 如果你 运行 子命令 'new' (
new_file_command
),我不想要求位置参数filename
,相反我想传递一个字符串并像这样创建新的文本文件:python reader.py new another.txt
- 如果你 运行 子命令 'edit' (
edit_file_command
) 我想在路径中传递现有文件并检查它(就像你在 [=18] 中使用type=int
=]) 然后可能将其传递给打开编辑器的函数,如下所示:python reader.py edit some.txt
同样,我不确定这是否是命令行 apps/scripts 的行为方式。我阅读了文档并查看了示例,但我仍然不清楚子解析器是如何工作的。我试着查看 Click 模块,但在我看来这更复杂。
感谢任何帮助。谢谢!
所以三个示例调用是:
python reader.py some.txt
python reader.py new another.txt
python reader.py edit some.txt
处理这些问题的最简单方法是使用一个 'optional' 位置,一个需要一个。
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
位置与 subparsers 参数(期望 new
或 edit
的位置)混合可能是个问题。
我希望 'python reader.py some.txt'
反对缺少 subparser 命令。 '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'、'new'、'edit' 都需要一个 'filename'.
试图避免使用 open
命令会造成比其价值更多的困难。
(最新的 argparse 中有一个 bug/feature 使子解析器可选,但您不应该在不真正了解问题的情况下利用它。)
有:
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