【问题标题】:Python argparse - user defined Action with 'store_true' behavoiurPython argparse - 具有“store_true”行为的用户定义操作
【发布时间】:2019-10-14 07:48:30
【问题描述】:

您好,我想我的解析器参数不能传递任何值,例如:

parser.add_argument('-s', '--staged', action=FooAction)

还有我的用户定义操作:

class FooAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        print("action")

当我尝试在没有任何值的情况下调用它时:

python my_script -s

我收到此错误消息:

test.py: error: argument -s/--staged: expected one argument

我知道我可以将操作“store_true”添加到我的参数中,但在此解决方案中,我无法将此参数的执行重定向到我定义的操作类。

有人知道如何修改 FooAction 以实现“store_true”动作行为吗?

编辑

设置 nargs=0 的类 Fooaction:

class FooAction(argparse.Action):
    def __init__(self, option_strings, dest, nargs=0, **kwargs):
        super(FooAction, self).__init__(option_strings, dest, nargs, **kwargs)
    def __call__(self, parser, namespace, values, option_string=None):
        print("action")

【问题讨论】:

  • 你看the implementation了吗?
  • 默认nargsNone,这意味着需要一个参数。查看store_truestore_const 子类的定义,我相信它设置了nargs=0
  • _StoreConstAction 类不是公开的,但 store_true 操作通过初始化 argparse.Actionnargs=0 来实现。所以,就照着做吧。
  • 好吧,即使我设置 nargs=0 和/或 const=True,它也会显示相同的错误消息
  • 你在哪里设置nargs=0。我认为您需要展示更多代码。

标签: python argparse


【解决方案1】:
import argparse

class FooAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        print("action")
        print(self)
        print(parser, namespace, values, option_string)

parser = argparse.ArgumentParser()
parser.add_argument('-s', '--staged', action=FooAction, nargs=0)
args = parser.parse_args()
print(args)

样本运行:

1151:~/mypy$ python3 stack56348020.py -s
action
FooAction(option_strings=['-s', '--staged'], dest='staged', nargs=0, const=None, default=None, type=None, choices=None, help=None, metavar=None)
ArgumentParser(prog='stack56348020.py', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True) Namespace(staged=None) [] -s
Namespace(staged=None)

使用您的init

import argparse

class FooAction(argparse.Action):
    def __init__(self, option_strings, dest, nargs=0, **kwargs):
        super(FooAction, self).__init__(option_strings, dest, nargs=nargs, **kwargs)
    def __call__(self, parser, namespace, values, option_string=None):
        print("action")
        print(parser, namespace, values, option_string)

parser = argparse.ArgumentParser()
a1 = parser.add_argument('-s', '--staged', action=FooAction)
print(a1)   # display the action object and most of its parameters
args = parser.parse_args()
print(args)

1208:~/mypy$ python3 stack56348020.py -s
FooAction(option_strings=['-s', '--staged'], dest='staged', nargs=0, const=None, default=None, type=None, choices=None, help=None, metavar=None)
action
ArgumentParser(prog='stack56348020.py', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True) Namespace(staged=None) [] -s
Namespace(staged=None)

add_argument 返回它创建的 Action 对象。我们通常忽略它,它保存到一个引用中,在调试时打印它可以很方便。

即使 Action 子类被标记为“私有”(使用_),查看它们的代码以了解它们如何自定义基类也是一个好主意。 Action 类本身并没有多大作用。默认操作使用_StoreAction。存储真/假子类_StoreConst_HelpAction 是唯一一个不在namespace 中存储某种值的人;它会退出系统。

【讨论】:

  • 像在__init__ 中那样设置nargs 也适用于我。
猜你喜欢
  • 2021-11-07
  • 2019-08-31
  • 2013-10-09
  • 2013-10-14
  • 1970-01-01
  • 2014-05-10
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多