如何用parent的方法装饰(包装)child的方法

How to decorate (wrap) child's method with parent's method

首先,这个问题可能是 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() 或者它会 以某种方式 (现在不知道如何写)检查,如果 child 添加了任何参数和然后将 self.parser.parse_args() 留给 child class。但我想,是否有可能一个愚蠢的想法是改变 parent 的 __init__ 使其表现得像 child 上的装饰器并做这样的事情(部分来自事实,即init 确实允许 return 除 None 之外的任何东西,它可能由于其他各种原因不起作用..?)

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

所以,有什么想法,我应该选择哪条路?我这样做的动机是,我希望使用这种 框架 (这意味着编写应用程序,继承自 Parent)的最终用户需要做尽可能少的工作尽可能(这意味着,将大部分内容移动到 Parent)。有没有什么合理的方法,怎么做?

将 parent class 中的 'middle' 部分移到 单独的 方法中。然后,您可以覆盖 just child:

中的那个方法
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

这基本上是另一个问题的至少一个答案告诉你要做的;将 parent __init__ 中的各个部分拆分为单独的方法,每个方法都可以单独覆盖。

如果您要将其作为一个框架,那么添加特定的挂钩也是一种选择。 parent 定义了它在特定点调用的 空方法 ,child class 可以实现以参与特定步骤。这里就是构建 ArgumentParser class 的地方,child class 可以添加到其中:

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

现在 child class 甚至不必再使用 super(); pre-digested 由框架提供所有需要的东西来更新解析器。