python - 'NoneType' 对象不能用装饰器类调用
问题描述
我正在学习使用此资源的装饰器类: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
解决方案
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
作为闭包变量保留的旧函数。
推荐阅读
- linq - 使用值对象查询 DBcontext 会在 EFCore 3.1 中显式返回客户端评估
- php - 如何使按钮跳转到指定的表格行
- for-loop - Fortran 中的隐含循环,用于类似累加和的数组
- c# - 将作为 JSON 值的 StringBuilder sb.ToString() 插入 SQL Server 数据库表?
- javascript - 如何将 promise 返回的数据推送到数组中?
- javascript - 尽管已安装软件包,但 Oppus Engine 未找到错误
- c# - 绑定到模型属性的 DataGridComboBoxColumn 不更新
- vue.js - Vue keep alive 在 $destroy 之后不再缓存
- java - spring boot中的文件上传输入
- python - Python 将函数传递给函数:我们为什么要使用装饰器?