子类化argparse Argument Parser [英] Sub-classing the argparse Argument Parser

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

问题描述

我正在尝试编写一个派生自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)

我可以将其等效作为脚本运行,并且可以.如果我从外壳运行它或导入到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.

也就是说,问题在于,当添加新的解析器时,已被SansParser实现覆盖的__init__方法不接受与原始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时,将创建新的ArgumentParser而不是创建新的SansParser(由于无限递归而失败).

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 Argument Parser的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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