我知道有类似的问题,但我的情况有所不同:参考代码:
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,就像这样的场景吗?
非常感谢!
答案 0 :(得分:1)
此时您无法传递对System.identityHashCode(this)
或self
的任何属性的引用。 self
行在执行@record_log
中的代码之前执行(方法已修饰),即在创建任何main
实例之前 - 实际上,甚至在定义之前MyClass
已完成!但请记住
MyClass
实际上只是
的语法糖@record_log(self.logs)
def test(self, n):
因此解决问题的一种方法是在test = record_log(self.logs)(test)
中重新定义test
,即
__init__
另请注意,您的装饰器未将任何参数传递给def __init__(self, log_location)
self.logs = logging(log_location)
self.test = record_log(self.logs)(self.test)
并且未返回结果。此外,它应该在模块级别(在课前)定义。
func
答案 1 :(得分:1)
您的代码有几个异议:
deco()
是多余的。您可以直接从wrap
返回record_log()
。
如果您只打算装饰MyClass
的方法,那么将log_object
传递给装饰器是没有意义的,因为始终会使用self.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