类中的装饰器:不能在装饰函数中使用 self

jim*_*iat 1 python decorator

我正在尝试使用装饰器实现自定义记录器,该装饰器将通过以下方式收集异常(稍后将它们保存到数据库):

import functools

class Log:
    def __init__(self):
        self.mssg = ""
        self.err = ""

class Parent:
    def __init__(self):
        self.logger = Log()

    def logging(fun):
        @functools.wraps(fun)
        def inner(*args):
            try:                
                print(fun.__name__)
                self.logger.mssg += fun.__name__ +" :ok, "  
                return fun(*args)

            except Exception as e:
                self.logger.err += fun.__name__ +": error: "+str(e.args) 
        return inner

    logging = staticmethod(logging)

class Child(Parent):
    def __init__(self, a, b): 
        self.a = a
        self.b = b

    @Parent.logging
    def sum_(self):
        return self.a + self.b
Run Code Online (Sandbox Code Playgroud)

然而,装饰器似乎“破坏”了方法和实例之间的链接,因为它不能再使用 self...运行时

c = Child(3,6)
c.sum_()
Run Code Online (Sandbox Code Playgroud)

我收到一条错误消息,self is not defined我还尝试了各种组合作为参数传递self.logger给函数,但我有点困惑,他们失败了......有人有一个可以解决我的问题的想法吗?

Ult*_*nct 5

您的代码存在一些问题。看看评论。

import functools

class Log:
    def __init__(self):
        self.mssg = ""
        self.err = ""

class Parent(object):
    def __init__(self):
        self.logger = Log()

    @staticmethod   #You can directly use staticmethod decorator!
    def logging(fun):
        @functools.wraps(fun)
        def inner(*args):
            self = args[0]  #Grab the first arg as self.
            try:                
                print(fun.__name__)
                self.logger.mssg += fun.__name__ +" :ok, "  
                return fun(self, *(args[1:]))  # Call the function using
                                               # self that we extracted.
            except Exception as e:
                self.logger.err += fun.__name__ +": error: "+str(e.args) 
        return inner

class Child(Parent):
    def __init__(self, a, b):
        super(Child, self).__init__()   #Don't forget call the parent ctor
        self.a = a
        self.b = b

    @Parent.logging
    def sum_(self):
        return self.a + self.b

c = Child(3,6)
print c.sum_()  #Outputs 9
Run Code Online (Sandbox Code Playgroud)