当前位置: 首页 > 面试题库 >

argparse-组合父解析器,子解析器和默认值

房星光
2023-03-14
问题内容

我想在脚本中定义不同的子解析器,两个子解析器均从同一个父级继承选项,但具有不同的默认值。但是,它没有按预期工作。

这是我所做的:

import argparse

# this is the top level parser
parser = argparse.ArgumentParser(description='bla bla')

# this serves as a parent parser
base_parser = argparse.ArgumentParser(add_help=False)
base_parser.add_argument('-n', help='number', type=int)


# subparsers
subparsers = parser.add_subparsers()
subparser1= subparsers.add_parser('a', help='subparser 1', 
                                   parents=[base_parser])
subparser1.set_defaults(n=50)
subparser2 = subparsers.add_parser('b', help='subparser 2',
                                   parents=[base_parser])
subparser2.set_defaults(n=20)

args = parser.parse_args()
print args

当我从命令行运行脚本时,得到的是:

$ python subparse.py b
Namespace(n=20)

$ python subparse.py a
Namespace(n=20)

显然,第二个set_defaults覆盖了父对象中的第一个。由于argparse文档中没有任何内容(非常详细),所以我认为这可能是一个错误。

有一些简单的解决方案吗?args之后,我可以检查变量,并None使用每个子解析器的预期默认值替换值,但这就是我期望argparse为我做的事情。

顺便说一下,这是Python 2.7。


问题答案:

set_defaults循环遍历解析器的操作,并设置每个default属性:

   def set_defaults(self, **kwargs):
        ...
        for action in self._actions:
            if action.dest in kwargs:
                action.default = kwargs[action.dest]

你的-n论点(一个action对象)时,你所定义的创建base_parser。使用创建每个子解析器时parents,该操作将添加到._actions每个子解析器的列表中。它没有定义新的动作;它只是复制指针。

因此,当您set_defaults在上使用时subparser2,您default可以为此共享操作修改。

此操作可能是subparser1._action列表中的第二项(h是第一项)。

 subparser1._actions[1].dest  # 'n'
 subparser1._actions[1] is subparser2._actions[1]  # true

如果第二条语句为True,则表示action两个列表中的相同。

如果您-n为每个子解析器分别定义,则不会看到此信息。它们将具有不同的动作对象。

我是根据我对代码的了解而工作的,而不是文档中的任何内容。最近在Cause
Python的argparse中指出了默认执行操作的内容是,该文档对add_argument返回Action对象一无所知。这些对象是代码组织的重要组成部分,但是在文档中却没有得到太多关注。

如果使用“解决”冲突处理程序,则通过引用复制父操作也会产生问题,并且需要重用父操作。
和Python错误问题:

http://bugs.python.org/issue22401

针对此问题的一种可能解决方案是(可选)复制操作而不是共享引用。这样option_stringsdefaults可以在子级中修改and
,而不会影响父级。



 类似资料:
  • 问题内容: 我正在使用Python 3.4,正在尝试与子解析器一起使用,并且我希望具有与Python 2.x中类似的行为,如果我不提供位置参数(以指示子解析器/子程序)我会收到一条有用的错误消息。即,随着我将得到以下错误消息: 我正在按照http://codingdict.com/questions/172394建议设置属性,但是这给了我Python 3.4.0错误: -完全追溯: 这是我的程序-

  • 问题内容: 我有以下代码(使用Python 2.7): 现在,我希望能够调用此程序,例如在普通程序或某些子命令后附加: 基本上,我需要声明可选的子解析器。我知道这并不是真正支持的方法,但是有任何解决方法或替代方法吗? 编辑:我得到的错误信息: 问题答案: 根据文档,带有(而不带有)的会自动打印版本号:

  • 问题内容: 我一直在这里和总体上搜索所有子解析器示例的分配,但似乎无法弄清楚这看似简单的事情。 我有两种var类型,其中一种具有约束,所以认为使用subparser是必经之路。例如-t允许“ A”或“ B”。如果用户通过“ A”,则进一步要求他们还指定它是“ a1”还是“ a2”。如果他们只是通过“ B”,那么什么也没有。 我可以这样做,让argparse返回给我什么类型的“ A”,或者只是“ B

  • 我尝试在一个java swing应用程序的缓存实例附近设置两个Oracle Coherence。这里可以找到解决方案。我的案子有点复杂,这就是游戏开始的地方。 在我的情况下,有一个帐户服务。它可以有两个endpoint:SIT和UAT。为了创建两个这样的服务,我需要加载Coherence的两个“实例”,以便用系统变量(tangosol.Coherence.cacheConfig)覆盖endpoin

  • 问题内容: 我的脚本定义了一个主解析器和多个子解析器。我想将论点应用于一些子解析器。到目前为止,代码如下所示: 如您所见,重复了两次。实际上,我还有更多的次级解析器。有没有一种方法可以遍历现有的子解析器以避免重复? 作为记录,我正在使用Python 2.7 问题答案: 这可以通过定义一个包含公共选项的父解析器来实现: 这将生成以下格式的帮助消息: 输出: 输出: 但是,如果您运行程序,则如果未指定

  • 基本上,我想结合这些g4文件: https://github.com/apache/groovy/tree/master/src/antlr 进入一个文件,我可以使用这个clojure库: https://github.com/aphyr/clj-antlr 它目前需要一个组合的解析器/词法器文件。如何破解这些文件,使它们以正确的语法存在于单个文件中?我已经排除了连接文件和删除lexer和para