如何用父母的方法装饰(包装)孩子的方法



首先,这个问题可能是重复的,但不知怎么的,我还没有弄清楚这些答案。假设我有:

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(),或者它会以某种方式(现在不知道具体如何写入)检查,如果child添加了任何参数,然后将self.parser.parse_args()留给child类。但我想,是否有可能有一个愚蠢的想法是将父级的__init__更改为像装饰器而不是子级,并做这样的事情(事实的一部分是,init确实允许返回除None之外的任何东西,它可能由于各种其他原因而不起作用…?)

class Child(Parent):
@super.__init__
def __init__(self):

那么,有什么想法吗?我应该选择哪条路?我这样做的动机是,我希望最终用户使用这样的框架(这意味着编写从Parent继承的应用程序),需要做尽可能少的工作(意味着将大多数事情转移到Parent中)。有没有合理的方法,如何做到这一点?

将父类中的"中间"部分移到单独的方法中。然后,您可以在子级中覆盖该方法:

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();它得到了它所需要的一切,由框架预先消化,以更新解析器。

最新更新