对 argparse 参数解析器进行子类化 [英] Sub-classing the argparse Argument Parser

查看:29
本文介绍了对 argparse 参数解析器进行子类化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个派生自 Python argparse ArgumentParser 类的解析器类.以下代码的大纲在命令行上运行良好,但在我的模块上下文中产生了一个我很难理解的错误.

I am trying to write a parser class derived from the Python argparse ArgumentParser class. The outlines of the following code work fine on the command line but generate an error I am struggling to understand in the context of my module.

代码(去掉了一些不重要的东西)如下:

The code (stripped down a little to remove the unimportant stuff) is as follows:

class SansParser(argparse.ArgumentParser):
"""Argument parser for preparing a SansModel fit or calculation

"""

def __init__(self):
    """Initialisation method for the parser class"""

    argparse.ArgumentParser.__init__(self)


    # Subparsers for the two commands 'calc' and 'fit'
    self.subparsers = self.add_subparsers()
    self.fit_parser = self.subparsers.add_parser('fit', help="Fit a dataset")
    self.fit_parser.add_argument('-d', '-data', '-dataset', type = str,
                                 dest = 'dataset',
                                 help = "The dataset to fit in SasXML format")
    self.fit_parser.set_defaults(func=fit)
    self.calc_parser = self.subparsers.add_parser('calc', prog='test')
    self.calc_parser.set_defaults(func=calculate)

我可以将其作为脚本运行,这很好.如果我从 shell 运行它或导入到 python 命令行并尝试实例化我得到的类:

I can run the equivalent of this as a script and its fine. If I run it from either shell or import into python command line and try to instantiate the class I get:

$ python sansmodel.py
    Traceback (most recent call last):
    File "sansmodel.py", line 57, in <module>
      parser = SansParser()
    File "sansmodel.py", line 41, in __init__
      self.fit_parser = self.subparsers.add_parser('fit', help="Fit a dataset")
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py",
    line 1064, in add_parser
      parser = self._parser_class(**kwargs)
 TypeError: __init__() got an unexpected keyword argument 'prog'

据我所知,argparse 中的代码本身在第 1064 行显式创建了prog"关键字,这是预期的行为,所以我对它出乎意料的地方感到困惑.我猜我的范围有什么问题?

As far as I can tell the code in argparse itself at line 1064 explicitly creates the 'prog' keyword and this is the expected behaviour so I'm confused as to where it is unexpected. I'm guessing I've got something backwards with the scope somehow?

推荐答案

除非您覆盖某些 argparse.ArgumentParser 行为,否则我建议创建一个解析器对象并将参数和子解析器添加到那个对象.

Unless you're overwritting some argparse.ArgumentParser behaviour, I recommend to create a parser object and add the arguments and the subparsers to that object.

也就是说,问题是当添加一个新的解析器时,__init__ 方法已经被 SansParser 实现覆盖,不接受与原来的ArgumentParser.

That said, the problem is that when adding a new parser the __init__ method, that has been overwritten by the SansParser implementation, doesn't accept the same arguments as the original ArgumentParser.

该问题的解决方法应该是这个:

A workaround to the problem should be this one:

self.subparsers._parser_class = argparse.ArgumentParser

这样,当 add_parser 被调用时,而不是创建一个新的 SansParser(由于无限递归而失败),一个新的 ArgumentParser> 将被创建.

This way, when add_parser is called, instead of creating a new SansParser (that would fail because of infinite recursion), a new ArgumentParser will be created.

这篇关于对 argparse 参数解析器进行子类化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆