有没有办法在 Argparser 中设置没有任何前缀的选项?

发布于 2024-10-06 04:44:58 字数 1517 浏览 0 评论 0原文

我正在使用 Argparser 来处理 CLI 程序的参数。但随着时间的流逝,我认为使用它并不是一个好主意。问题来了。我想使用没有任何前缀字符的选项。就像git commitsvn move。我搜索了一下,发现 Argparse 有一个 add_subparser() 方法。让我们填充我们的 foo prog:

parser = argparse.ArgumentParser(prog='foo', usage='%(prog)s [options]')

subparsers = parser.add_subparsers(help='sub-command help')
parser_a = subparsers.add_parser('add', help='a help')
parser_a.add_argument('-ap', '--add-project',
                    nargs='*',
                    action='store',
                    help="Add project")

parser_d = subparsers.add_parser('del', help='a help')
parser_d.add_argument('-dp', '--delete-project',
                    nargs='*',
                    action='store',
                    help="Delete project")

args = parser.parser_args()

现在让我们使用选项执行 foo 并打印 args 命名空间(我没有过去整个代码,你明白了)

$ ./foo del
Namespace(delete_project=None)
$ ./foo add
Namespace(add_project=None)

:看,如果我执行选项 deladd_project 不会传递给变量 args。如果我的 main() 函数中有一个“if 子句”,这会导致问题,就像

def main(args):

   if args.delete_project:
      ...
   if args.add_project:
      ...

我会得到一个 AttributeError 异常,即命名空间没有名为 add_project 的属性如果我执行./foo del。除此之外,我无法将任何参数传递给选项 deladd。我还将 prefix_chars 设置为空字符串,但这也不起作用。

有什么方法可以处理呢? argparse 是否能够创建 git、svn 等选项,或者我应该创建自己的函数并自己处理所有参数?

I'm using Argparser to handle arguments for my CLI prog. But as the time passed I think that It's not a good Idea to use it. Here comes the problem. I want to use options without any prefix character. Like git commit or svn move. I've searched a little and found that Argparse has a add_subparser() method. Let us populate our foo prog:

parser = argparse.ArgumentParser(prog='foo', usage='%(prog)s [options]')

subparsers = parser.add_subparsers(help='sub-command help')
parser_a = subparsers.add_parser('add', help='a help')
parser_a.add_argument('-ap', '--add-project',
                    nargs='*',
                    action='store',
                    help="Add project")

parser_d = subparsers.add_parser('del', help='a help')
parser_d.add_argument('-dp', '--delete-project',
                    nargs='*',
                    action='store',
                    help="Delete project")

args = parser.parser_args()

Now let execute foo with options and print args namespace(I didn't the past the whole code, you get the point):

$ ./foo del
Namespace(delete_project=None)
$ ./foo add
Namespace(add_project=None)

As you see, if I execute the option del, add_project is not passed to the variable args. That causes problems if I have an "if clause" in my main() function like

def main(args):

   if args.delete_project:
      ...
   if args.add_project:
      ...

I'll get an AttributeError exception, that the Namespace has no attribute with the name add_project if I execute ./foo del. Besides that, I'm not able to pass any argument to the options del and add. I've also set prefix_chars to an empty string, that didn't work either.

What is way to handle it ? Is argparse capable to create options like git,svn, etc.. or should I create my own function and handle all arguments myself ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

为人所爱 2024-10-13 04:44:58

argparse 文档推荐这样的内容,而不是 if 语句

parser_X.set_defaults(action=action_func)
args.action(args)

: add_action 将查看 add_project,del_action 将查看 del_project。

Instead of your if statements, the argparse docs recommend something like this:

parser_X.set_defaults(action=action_func)
args.action(args)

Then the add_action will look at add_project, and del_action at del_project.

臻嫒无言 2024-10-13 04:44:58

编辑:显然 default 的默认值是 None,这意味着我们没有,所以您必须使用 True 和 < code>False (无论如何这是正确的方法)。

当您将参数添加到解析器时,您需要添加default

parser_a.add_argument('-ap', '--add-project',
                    nargs = '*',
                    action = 'store_true',
                    default = False,
                    help = "Add project")

您可以查看add_argument方法的文档此处。 (我意识到 argparse 文档布局并不是最有利于弄清楚如何做示例中未提及的事情)

此外,正如 Tobu 在他的回答中适当指出的那样,未使用的子解析器不会被调用,因此如果不至少在 try: 块中保护您的代码,您就无法安全地探测它们的值。但是,实际上您应该使用将 action 与子解析器关联的功能,除非您遇到更复杂的情况,它们需要共享状态。

Edit: Apparently the default for default is None, which means we don't have one, so you'll have to use True and False (which is the right way anyhow).

You need to add the default when you add your argument to the parser:

parser_a.add_argument('-ap', '--add-project',
                    nargs = '*',
                    action = 'store_true',
                    default = False,
                    help = "Add project")

You can see the documentation for the add_argument method here. (I realize the argparse doc layout isn't the most conducive to figuring out how to do things that aren't called out in the examples)

Also, as Tobu appropriately points out in his answer, the unused subparsers don't get invoked, so you can't safely probe their values without at least protecting your code in a try: block. However, really you should use the functionality of associating an action with your subparsers unless you have a much more complex situation where they need to share state.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文