Python 如何通过分解两个非常相似的类为Argparse传递类中的参数

Python 如何通过分解两个非常相似的类为Argparse传递类中的参数,python,oop,argparse,Python,Oop,Argparse,我有以下代码: def main(args): """ Description of main """ print args if __name__ == '__main__': class DefaultListAction(argparse.Action): CHOICES = ['ann','netmhcpan','comblib_sidney2008','consensus','smm','smmpmbec','netmhcco

我有以下代码:

def main(args):
    """
    Description of main
    """
    print args


if __name__ == '__main__':
    class DefaultListAction(argparse.Action):
        CHOICES = ['ann','netmhcpan','comblib_sidney2008','consensus','smm','smmpmbec','netmhccons']
        def __call__(self, parser, namespace, values, option_string=None):
            if values:
                for value in values:
                    if value not in self.CHOICES:
                        message = ("invalid choice: {0!r} (choose from {1})"
                                .format(value,
                                        ', '.join([repr(action)
                                                    for action in self.CHOICES])))

                        raise argparse.ArgumentError(self, message)
                setattr(namespace, self.dest, values)

    class DefaultListAction_Frames(argparse.Action):
        CHOICES = ['R','F','6']
        def __call__(self, parser, namespace, values, option_string=None):
            if values:
                for value in values:
                    if value not in self.CHOICES:
                        message = ("invalid choice: {0!r} (choose from {1})"
                                .format(value,
                                        ', '.join([repr(action)
                                                    for action in self.CHOICES])))

                        raise argparse.ArgumentError(self, message)
                setattr(namespace, self.dest, values)

    parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("-iedb",help="IEDB tools options: ann, comblib_sydney2008, consensus, netmhcpan, smm, smmpmbec, netmhccons", \
              action=DefaultListAction, nargs='*', default=[''], \
              metavar='iedb_tools')
    parser.add_argument("-f",help="Frame to translate insert: (F)orward three frames, (R)everse three frames or (6) frames F + B.  Default F.", \
              action=DefaultListAction_Frames, nargs=1, default=['F'], \
              metavar='frames')
    args = parser.parse_args()
    main(args)
基本上,有两个
argparse.ArgumentParser.add_argument()
,它们中的每一个都将一个类作为
操作中的参数

我的问题是,考虑到这两种方法之间的唯一区别是
选项
参数,如何将
类DefaultListAction(argparse.Action)
和类
DefaultListAction_帧(argparse.Action)
分解


如何在
argparse.ArgumentParser.add_argument()

中将这些
选项作为参数传递
参数作为
self.CHOICES
可用。它没有在任何现有的
Action
子类中使用,但没有理由不使用它

解析器将使用它在值传递到
操作之前测试这些值。在这个测试中,这似乎与您自己的使用没有冲突,但我不能排除这种可能性

action.choices
也用于帮助格式化,尽管
metavar
参数会覆盖该选项

class ListAction(argparse.Action):
    # change self.CHOICES to self.choices
    def __call__(self, parser, namespace, values, option_string=None):
        if values:
            for value in values:
                if value not in self.choices:
                    message = ("invalid choice: {0!r} (choose from {1})"
                            .format(value,
                                    ', '.join([repr(action)
                                                for action in self.choices])))

                    raise argparse.ArgumentError(self, message)
            setattr(namespace, self.dest, values)

# should behave just like the -f argument
parser.add_argument("-g",help="Frame to translate insert: (F)orward three frames, (R)everse three frames or (6) frames F + B.  Default F.", \
          action=ListAction, nargs=1, default=['F'], \
          choices=['R','F','6'])
允许将
选项
作为元变量的帮助(用于说明)

当解析
操作时,选项
仅用于
\u check\u value
,它由
\u get\u values
调用

def _check_value(self, action, value):
    # converted value must be one of the choices (if specified)
    if action.choices is not None and value not in action.choices:
        args = {'value': value,
                'choices': ', '.join(map(repr, action.choices))}
        msg = _('invalid choice: %(value)r (choose from %(choices)s)')
        raise ArgumentError(action, msg % args)
立即看来,您可以将默认的
存储
操作与
选项一起使用

parser.add_argument("-e",help="Frame to translate insert: (F)orward three frames, (R)everse three frames or (6) frames F + B.  Default F.", \
          nargs=1, default=['F'], choices=['R','F','6'])
我看不出你的定制动作有什么不同。但我没有详细研究或测试它们

=================

另一种方法是将一个新操作子类化:

class DefaultListAction_Frames(DefaultListAction):
    CHOICES = ['R','F','6','X']
如果
\uuuu调用\uuuu
方法相同,则不必重复

另一种方法是使用工厂函数为每个
DefaultListAction
操作赋予其自己的
选项
属性。
FileType
就是这样一个类-它创建了一个自定义的
type
函数


type
函数是另一个可以自定义值检查的地方<代码>类型
用于值转换和测试,而如果您想以某种特殊方式保存值,则自定义操作类最为有用。

self.choices
应包含
add\u参数
中给出的
choices
参数。有关
操作
类,请参见
\uuuu初始化
<代码>操作。选项
用于
\u check\u value
方法和帮助格式。它没有在任何
操作
方法中使用,但我不知道为什么它不能使用。@hpaulj:请举个例子。
class DefaultListAction_Frames(DefaultListAction):
    CHOICES = ['R','F','6','X']