我是一名 Python 初学者,刚接触 argparse 模块,所以请耐心等待。我想使用 argparse 来解析我正在制作的一个简单程序,但我认为我对它的理解是错误的。基本上,我想制作一个可以管理和编辑文件的程序。
管理文件: [命令] [文件] 这将允许基本的文件管理命令,如下所示:
C .\file.txt # create a file
编辑文件: [打印] [工作文件的内容] 或者 [编辑] [工作文件的内容]
像这样:
E -usr "mark b" -pwd "password123" # edit the username stored using -usr and password using -pwd
P -usr # print the username
由于打印和编辑使用了很多相同的选项,如用户名、帖子、传记等,我想我应该将它们放在单独的子解析器中。我将文件管理命令放入主解析器中,这要求它位于我不想要的 P 和 E 命令之前,所以我尝试将它们也放入子解析器中,但仍然出现错误。
F -C file
usage: scratch.py [-h] {-F,-P,-E} ...
scratch.py: error: argument {-F,-P,-E}: invalid choice: 'file' (choose from '-F', '-P', '-E')
P -usr
usage: scratch.py [-h] {-P,-E} ...
scratch.py: error: unrecognized arguments: -P -usr
这是我的代码:
def parser(tokens):
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
# file management commands
f_parser = subparsers.add_parser('-F', description='.dsu file management')
f_parser.add_argument('-C', help='Create new .dsu file', type=Path)
f_parser.add_argument('-D', help='Delete .dsu file', type=Path)
f_parser.add_argument('-R', help='Read .dsu file', type=Path)
f_parser.add_argument('-Q', help='Quit PyJournal', type=Path)
f_parser.add_argument('-O', help='Load a .dsu file', type=Path)
# print parser
p_parser = subparsers.add_parser('-P', help='Print Profile content')
p_parser.add_argument('-usr', action='store_true', dest='username')
p_parser.add_argument('-pwd', action='store_true', dest='password')
p_parser.add_argument('-bio', action='store_true', dest='bio')
p_parser.add_argument('-posts', action='store_true', dest='posts')
p_parser.add_argument('-post', action='store', dest='post', type=int)
p_parser.add_argument('-all', action='store_true', dest='all')
# edit parser
e_parser = subparsers.add_parser('-E', help='Edit Profile content')
e_parser.add_argument('-addpost', action='store', dest='new_post')
e_parser.add_argument('-delpost', action='store', dest='del_post', type=int)
e_parser.add_argument('-usr', action='store', dest='username')
e_parser.add_argument('-pwd', action='store', dest='password')
e_parser.add_argument('-bio', action='store', dest='bio')
args = parser.parse_args(tokens)
if args.all:
args.username = True
args.password = True
args.bio = True
args.posts = True
return vars(args)
理想情况下,我不想在文件管理命令前面放置额外的命令,同时能够解析我的打印和编辑命令。我应该使用子解析吗?我希望这是有道理的。
子解析器通常用于以类似于 CLI 实用程序的方式实现子命令模式,例如
git
和 docker
(例如 git commit
、git checkout
、docker info
、docker run
是使用子命令的一些示例)顶级命令)。
请注意,子命令通常是不以
-
开头的整个单词,因为 -
通常保留用于修改实用程序功能的标志(例如 git -C /path/to/repo/.git log -p
将在 上设置
-C
标志) git
指定要打开哪个存储库,-p
指定 log
将差异包含在日志输出中)。
在 argparse 的设计中,现有 CLI 实用程序中的规范很大程度上影响了解析通常设计的工作方式,因此 argparser 将简单地忽略具有以
-
开头的命令的子解析器,因为它假定传入的标记以 -
开头只是标志而不是子命令。事实上,这个问题已经被报告了,并被作为无效/不会被 CPython 修复而关闭。
如果您想使用子命令模式,只需删除每个命令之前的
-
字符,像 F -C file
这样的命令就会起作用 - 您的预期用例在 -
之前不包含 F
,所以它没有'首先将其包含在解析器规范中对您来说甚至没有意义。