Spy*_*dai 5 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()
Run Code Online (Sandbox Code Playgroud)
但是,有一个这样的错误:
@record_log(self.logs)
NameError: name 'self' is not defined
Run Code Online (Sandbox Code Playgroud)
在这样的场景中,我应该在装饰器函数中使用实例属性 self.logs 吗?
非常感谢!
对于您的代码有几个反对意见:
deco()是多余的。可以直接wrap从回来record_log()。
如果您只打算装饰的方法,那么传递给装饰器MyClass是没有意义的,因为它将始终被使用。否则,请考虑将装饰器移动到模块级别,正如其他人已经建议的那样。log_objectself.logs
装饰方法的返回值当前丢失。
对修饰函数的调用不会传递self给它。
因此,正确的代码是:
class MyClass(object):
def __init__(self, log_location):
self.logs = logging(log_location)
def record_log(func):
""" this is the decorator function
"""
def wrap(self):
rs = func(self)
# use log object to record log
if rs:
print 1
self.logs.record('success')
else:
print 2
self.logs.record('fail')
return rs
return wrap
@record_log
def test(self):
rs = do_some_thing
if rs:
return True
return False
Run Code Online (Sandbox Code Playgroud)