在 Python 中使用 argparse 进行子解析或不进行子解析

问题描述 投票:0回答:1

我是一名 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)

理想情况下,我不想在文件管理命令前面放置额外的命令,同时能够解析我的打印和编辑命令。我应该使用子解析吗?我希望这是有道理的。

python argparse
1个回答
0
投票

子解析器通常用于以类似于 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
,所以它没有'首先将其包含在解析器规范中对您来说甚至没有意义。

© www.soinside.com 2019 - 2024. All rights reserved.