如何确保在子程序在装饰器中覆盖父方法之前始终调用父方法?

时间:2016-02-01 21:52:01

标签: python python-2.7 oop

所以我有一个父类:

class Parent(Object):
    def function(self):
        do_something()

许多儿童班:

class Child1(Parent):
    def function(self):
        do_something_else_1()

class Child2(Parent):
    def function(self):
        do_something_else_2()

...

我想确保始终在子function()之前调用父function(),以便每次调用function()也会调用do_something()否这课很重要。现在,我知道我可以做类似的事情:

class Child1(Parent):
    def function(self):
        super(Child1, self).function()
        do_something_else_1()

class Child2(Parent):
    def function(self):
        super(Child2, self).function()
        do_something_else_2()

...

但我宁愿不为每个子类做这个,因为这些子类是动态生成的,因为这些子类本身正在进一步扩展。相反,我想做一些看起来像

的事情
class Child1(Parent):
    @call_parent
    def function(self):
        do_something_else_1()

class Child2(Parent):
    @call_parent
    def function(self):
        do_something_else_2()

...

写一个装饰器来完成同样的任务。

我有两个问题:

  1. 这是个好主意吗?我是否按照预期的方式使用装饰器和功能覆盖?
  2. 我怎么去写这个装饰师?

2 个答案:

答案 0 :(得分:5)

  

这是一个好主意吗?我是否按照预期的方式使用装饰器和功能覆盖?

如果不了解有关系统的详细信息,这个问题很难回答。 仅从抽象示例中看起来没问题,但用super()之类的内容替换显式且清晰的@call_parent调用并不是一个好主意。

每个人都知道或者可以很容易地找出super()做什么,装饰者只会引起混淆。

  

我怎么去写这个装饰师?

不要写装饰器,而是可以使用template method

class Parent(Object):

    def function(self):
        do_something()
        do_something_in_child()

    def do_something_in_child():
        pass

现在,在子课程中,您只能覆盖do_something_in_childfunction只会停留在Parent,因此您确定始终会调用do_something()

class Child1(Parent):

    def do_something_in_child(self):
        do_something_else_1():

class Child2(Parent):

    def do_something_in_child(self):
        do_something_else_2():

class Child3(Parent):
    # no override here, function() will do the same what it does in Parent
    pass

答案 1 :(得分:0)

我不熟悉Python,但你可以这样:

# Function in childredn. Overrides parent one.
def function(self):
        # child code
        super().function() #however it is used
        # more child code 

如果这不合理,请查看模板方法设计模式。

# Function in parent. Do not override this one
def function(self):
    # your parent code
    function_do_something()
    # more code if you need it

# function in parent. Children overryde this one
def function_do_something():
...

并且,你总是可以让function_do_something()为void,以便只执行你的父构造函数。