更改装饰器中的实例属性

时间:2018-08-22 20:39:38

标签: python decorator self

我已经搜索了这个问题,但没有找到我要寻找的答案。

基本上,我想将类构造函数包装在try / except子句中,以便它忽略构造函数内部的特定类型的错误(但无论如何都要记录并打印错误)。我发现做到这一点的最好方法是用装饰器包装我的方法,因为我想在其他类中做同样的事情,但是我不想一直重复相同的try / except子句。

但是,对象必须记住构造函数中是否发生了异常(将其保存在该对象的布尔属性中),以便稍后在该对象调用特定方法时可以使用该信息。后来。因此,我尝试执行以下代码段中的操作:

def detectAndIgnoreErrors(fn):
    def wrappedFunc(*args, **kwargs):
        try:
            fn(*args, **kwargs)
            self.HasAnExceptionOccurredInInit = False
        except KeyError as e:
            self.HasAnExceptionOccurredInInit = True
            # Log and print exception
        except RuntimeError as e:
            self.HasAnExceptionOccurredInInit = True
            # Log and print exception

    return wrappedFunc


class Foo(FooSuperclass):

    @detectAndIgnoreErrors
    def __init__(self):
        # Do stuff that may raise exceptions
        pass

    def doStuff(self):
        if self.HasAnExceptionOccurredInInit:
            # Do stuff
            pass
        else:
            # Do other stuff
            pass

fooInstance = Foo()
fooInstance.doStuff()

这里的想法是让对象忽略构造函数中的错误,然后在调用doStuff()方法时,对象会记住HasAnExceptionOccurredInInit是否发生异常并调整其行为相应地。但是,解释器说self名称没有定义(这很有意义,因为我试图在类范围之外访问它)。

然后,我尝试将装饰器作为类成员,然后再尝试将其作为Foo的父类中的类成员,但是这些替代方法均无效。

经过一番研究,我意识到装饰器是在定义时而不是在执行时解析的,因此无法使用self这样的方式,因此我不知道该如何解决这个问题。

如果有人知道如何解决此问题(或者也许是更好的解决方案而不是装饰器),将不胜感激。

1 个答案:

答案 0 :(得分:2)

包装的函数没有名为self的参数;如果要假设fn是一种方法,则需要特别指定。

def detectAndIgnoreErrors(fn):
    def wrappedFunc(self, *args, **kwargs):
        try:
            fn(self, *args, **kwargs)
            self.HasAnExceptionOccurredInInit = False
        except KeyError as e:
            self.HasAnExceptionOccurredInInit = True
            # Log and print exception
        except RuntimeError as e:
            self.HasAnExceptionOccurredInInit = True
            # Log and print exception

    return wrappedFunc