在父类方法上使用子类中指定的装饰器

时间:2019-08-07 15:21:01

标签: python

假设我有两个类ChildParent(这是Child的基类)。我还有另一个类Dec,其中包含一个装饰器dec,我想在Parent方法中使用它。我希望能够指定Dec中应使用的Child对象。

这是我到目前为止尝试过的:

class Dec():
    def dec(self, func):
        def wrapper(self):
            print("Before func call")
            func(self)
            print("After func call")

        return wrapper

class Parent():
    dec = None

    @dec.dec
    def p(self):
        print('hello')

dec = Dec()

class Child(Parent):
    a = dec

t = Child()
t.p()

所以,我得到了

AttributeError: 'NoneType' object has no attribute 'dec'

@dec.dec

是否可以选择在Child类中使用带有装饰器的类?

2 个答案:

答案 0 :(得分:0)

您在这里遇到的问题与范围界定有关。

运行此代码时,我收到此错误:

"ignore_above": 256

使用它,您可以看到自己存在一些范围界定问题。在此文件中,您多次定义...<stack trace>... File ".\__main__.py", line 10, in <module> class Parent(): File ".\__main__.py", line 13, in Parent @dec.dec AttributeError: 'NoneType' object has no attribute 'dec' 。与其像在第11行上那样实例化dec,不如将Dec定义为Dec.dec(...),可以从类本身调用它,而不仅仅是类的实例。

这是一个可能的解决方案:

@classmethod

这提供了我认为是预期的行为:

class Dec():
    @classmethod
    def dec(self, func):
        def wrapper(self):
            print("Before func call")
            func(self)
            print("After func call")

        return wrapper

class Parent():
    @Dec.dec
    def p(self):
        print('hello')


class Child(Parent):
    pass # you didn't really need anything here.

t = Child()
t.p()

答案 1 :(得分:0)

作为另一种解决方案的替代方法,这是另一种方法:

为您的流程定义某种通用结构,然后为您的类更改“装饰器”或“扩展处理器” ...

class Parent:
    extended_processor = None

    def p(self):
        if (self.extended_processor is not None and 
            hasattr(self.extended_processor, "before") and 
            callable(self.extended_processor.before)):
            self.extended_processor.before()

        print('parent says hello')

        if (self.extended_processor is not None and 
            hasattr(self.extended_processor, "after") and 
            callable(self.extended_processor.after)):
            self.extended_processor.after()

class ex_proc:
    @classmethod
    def before(cls):
        print("ex_proc before")

    @classmethod
    def after(cls):
        print("ex_proc after")

class Child(Parent):
    extended_processor = ex_proc

print("\n=== PARENT ===")
par = Parent()
par.p()

print("\n=== CHILD ===")
chi = Child()
chi.p()

这提供了以下输出:

=== PARENT ===
parent says hello

=== CHILD ===
ex_proc before
parent says hello
ex_proc after