python - 如何在类中使用装饰器

标签 python decorator python-decorators

我知道有类似的问题,但我的场景有些不同:引用代码:

class MyClass(object):
    def __init__(self, log_location)
        self.logs = logging(log_location) # create log object by the log_location, this object should be used by the decorator fucntion

    def record_log(log_object): 
        """ this is the decorator function
        """
        def deco(func):
            def wrap(*args, **kwargs):
                rs = func()

                # use log object to record log
                if rs:
                    log_object.record('success')
                else:
                    log_object.record('fail')

            return wrap
        return deco

   @record_log(self.logs) 
   def test(self):
       rs = do_some_thing
       if rs:
            return True
       return False

def main():
    my_class = MyClass()
    my_class.test()   

但是,出现了这样的错误:

@record_log(self.logs)
NameError: name 'self' is not defined

在这种情况下,我应该在装饰器函数中使用实例属性 self.logs 吗??

非常感谢!

最佳答案

此时您不能传递对self 的引用或self 的任何属性。 @record_log 行在 main 中的代码执行之前执行(该方法被修饰),即在 MyClass 的任何实例创建之前全部——事实上,甚至在 MyClass 的定义完成之前!但请记住这一点

@record_log(self.logs) 
def test(self, n):

实际上只是

的语法糖
test = record_log(self.logs)(test)

因此,解决您的问题的一种方法是在您的 __init__ 中重新定义 test,即

def __init__(self, log_location)
    self.logs = logging(log_location)
    self.test = record_log(self.logs)(self.test)

另请注意,您的装饰器不会将任何参数传递给 func 并且不会返回结果。此外,它可能应该在模块级别(在类之前)定义。

def record_log(log_object): 
    def deco(func):
        def wrap(*args, **kwargs):
            rs = func(*args, **kwargs)   # pass parameters
            if rs:
                log_object.record('success')
            else:
                log_object.record('fail')
            return rs   # return result
        return wrap
    return deco

关于python - 如何在类中使用装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29792528/

相关文章:

python - 为 python 安装 stringtemplate3

python - 如何检查NCCL的版本

Python 3.5 装饰器和函数域

Python 装饰器在调用函数之前的导入期间运行

Python 用可变数量的位置参数和可选参数装饰方法

python - 类和方法的一个装饰器

python - 当组可能不存在时,迭代多个 DataFrame 中的组

python - 如何在python中等待用户输入5秒

python - 在另一个装饰器之前使用 PyQt 4's ' pyqtSlot' 装饰器的奇怪行为

c++ - 在引用上跳过重载函数