我正在使用以下资源来学习装饰器类:
http://book.pythontips.com/en/latest/decorators.html#decorator-classes
所介绍的课程基本上是这样的:
class logit(object):
def __init__(self, logfile='out.log'):
self.logfile = logfile
def __call__(self, func):
log_string = func.__name__ + " was called"
print(log_string)
# Open the logfile and append
with open(self.logfile, 'a') as opened_file:
# Now we log to the specified logfile
opened_file.write(log_string + '\n')
# Now, send a notification
self.notify()
def notify(self):
# logit only logs, no more
pass
和通话:
@logit()
def myfunc1():
pass
myfunc1()
我得到一个错误:
>>> myfunc1()
[...]
TypeError: 'NoneType' object is not callable
答案 0 :(得分:2)
logit.__call__
确实返回None
,而您正在通过修饰来进行myfunc1 = logit()(myfunc1)
。 myfunc
现在为None
。
据我了解,您想记录装饰函数的每个调用。在这种情况下,__call__
必须构建一个新函数并return
。
类似
def __call__(self, func):
def new_func(*args, **kwargs):
log_string = func.__name__ + " was called"
print(log_string)
# Open the logfile and append
with open(self.logfile, 'a') as opened_file:
# Now we log to the specified logfile
opened_file.write(log_string + '\n')
# Now, send a notification
self.notify()
# execute func
return func(*args, **kwargs)
return new_func
现在
@logit()
def myfunc1():
pass
确实
myfunc1 = logit()(myfunc1)
即它将名称myfunc1
重新分配给__call__
内置的新功能。这个新函数执行日志记录逻辑,然后执行旧的myfunc1
并将其保留在名称func
下作为封闭变量。