我有一个我无法修改的基类(代码可能有其他错误,但请忽略它们)
class BaseClass(object):
def __init__(self):
self.parser = argparse.ArgumentParser()
self.parser.add_argument("arg1", choices=("a", "b"))
我想要的是按以下方式覆盖arg1
class DerivedClass(BaseClass):
def __init__(self):
BaseClass.__init__(self)
self.parser.add_argument("arg1", choices=("a", "c", "d"))
答案 0 :(得分:3)
如果您无法修改基类实现,则可以进入parser
的属性并修改您关注的特定操作。这是一段代码示意图:
from base import BaseClass
def _modify_choices(parser, dest, choices):
for action in parser._actions:
if action.dest == dest:
action.choices = choices
return
else:
raise AssertionError('argument {} not found'.format(dest))
class MySubClass(BaseClass):
def __init__(self):
super(MySubClass, self).__init__()
_modify_choices(self.parser, 'arg1', ('a', 'b', 'c'))
def main():
inst = MySubClass()
inst.parser.parse_args()
if __name__ == '__main__':
exit(main())
用法:
$ python subclass.py d
usage: subclass.py [-h] {a,b,c}
subclass.py: error: argument arg1: invalid choice: 'd' (choose from 'a', 'b', 'c')
请注意,这会涉及私有实现细节(特别是ArgumentParser._actions
),但是否则使用公共接口。
答案 1 :(得分:1)
add_argument
创建一个Action
对象,该对象对add_argument
调用中给出的参数进行编码。创建后可以读取和/或修改它们。
class BaseClass(object)
def __init__(self):
self.parser = argparse.ArgumentParser()
self.arg = self.parser.add_argument("arg1", choices=("a", "b"))
# self.arg is now the Action object defined by this add_argument method
class DerivedClass(BaseClass):
def __init__(self):
BaseClass.__init__(self)
# modify the choices attribute of self.arg
self.arg.choices = ("a","b","c")
也可以在parser._actions
列表中找到该Action对象,但我更喜欢在我自己的代码中保存引用。
(此代码尚未经过测试,因此可能会有两两个错误。)
class BaseClass(object):
def __init__(self):
self.parser = argparse.ArgumentParser(prog="BASE")
self.parser.add_argument("arg1", choices=("a", "b"))
self.parser.add_argument('-f','--foo')
class DerivedClass(BaseClass):
def __init__(self):
BaseClass.__init__(self)
self.parser.prog = "DERIVED"
print(self.parser._actions)
在创建DerivedClass时显示此列表:
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
_StoreAction(option_strings=[], dest='arg1', nargs=None, const=None, default=None, type=None, choices=('a', 'b'), help=None, metavar=None),
_StoreAction(option_strings=['-f', '--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)]
添加:
idx = [a.dest for a in self.parser._actions].index('arg1')
self.parser._actions[idx].choices = ("a","b","c")
p1 = BaseClass()
p1.parser.print_help()
p2 = DerivedClass()
p2.parser.print_help()
产生2次使用:
usage: BASE [-h] [-f FOO] {a,b}
positional arguments:
{a,b}
optional arguments:
-h, --help show this help message and exit
-f FOO, --foo FOO
和
usage: DERIVED [-h] [-f FOO] {a,b,c}
positional arguments:
{a,b,c}
optional arguments:
-h, --help show this help message and exit
-f FOO, --foo FOO