首先,这个问题可能是duplicate,但不知何故,我还没有理解这些答案。说我有:
import argparse
class Parent:
def __init__(self):
self.parser = argparse.ArgumentParser()
self.parser.add_argument("user")
# parse the argument
self.parser.parse_args()
class Child(Parent):
def __init__(self):
# here self.parser is not defined
# self.parser.add_argument("password")
super().__init__()
# here args are already parsed and
# self.parser does not include args
# self.parser.add_argument("password")
if __name__ == '__main__':
Child()
这是我想编写的代码的最小工作示例(类似于命令行应用程序框架。我的设置基本上如下
class Parent:
def __init__(self):
# do some stuff starting stuff
# middle
# do some ending stuff
class Child(Parent):
def __init__(self):
# do something in the middle of Parent init
在我的案例中有简单的部分解决方法。当Parent
可能不会self.parser.parse_args()
或以某种方式(不知道如何正确写入)检查时,如果子项添加了任何参数然后离开{{1}到了儿童班。但我想,是否有可能一个愚蠢的想法是改变父亲的self.parser.parse_args()
表现得像一个装扮者而不是孩子,并做这样的事情(事实的一部分, init 允许要返回__init__
以外的任何内容,它可能不会因各种其他原因而起作用..?)
None
那么,任何想法,我应该选择哪条路?我的动机是,我希望最终用户,谁将使用这样的框架(这意味着编写应用程序,继承自Parent)需要做尽可能少的工作(这意味着,移动)大多数事情变成父母)。有什么合理的方法,怎么做?
答案 0 :(得分:1)
移动中间'在父类中分配到单独的方法。然后,您可以在子项中覆盖只该方法:
class Parent:
def __init__(self):
self._construct_parser()
# parse the argument
self.parser.parse_args()
def _construct_parser(self):
self.parser = argparse.ArgumentParser()
self.parser.add_argument("user")
class Child(Parent):
def _construct_parser(self):
super()._construct_parser()
# add on to self.parser
这基本上是另一个问题的答案中至少有一个告诉你要做的事情;将父__init__
中的各个部分拆分为单独的方法,每个方法都可以单独覆盖。
如果您将此作为框架,那么添加特定挂钩也是一种选择。父类定义它在特定点调用的空方法,子类可以实现以参与特定步骤。这就是ArgumentParser
类已经构建并且子类可以添加到它的位置:
class Parent:
def __init__(self):
self._construct_parser()
# parse the argument
self.parser.parse_args()
def _construct_parser(self):
self.parser = argparse.ArgumentParser()
self.parser.add_argument("user")
self.update_parser(self.parser)
# hook method
def update_parser(self, parser):
pass
class Child(Parent):
def update_parser(self, parser):
# add to parser
现在,儿童班甚至不再需要使用super()
;它被所有需要的东西(由框架预先消化)传递给更新解析器。