Python ';非类型';对象不能用装饰器类调用
我正在学习使用此资源的decorator类:Python ';非类型';对象不能用装饰器类调用,python,class,decorator,python-decorators,Python,Class,Decorator,Python Decorators,我正在学习使用此资源的decorator类: 所介绍的课程基本上是这样的: 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)
所介绍的课程基本上是这样的:
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.\uu调用\uu
确实返回None
,您正在通过装饰执行myfunc1=logit()(myfunc1)
myfunc
现在是None
据我所知,您希望记录装饰函数的每个调用。在这种情况下,\uuuu call\uuu
必须构建一个新函数并返回它
差不多
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
现在
做
i、 e.它将名称myfunc1
重新分配给内置的新函数\uuuu调用\uuu
。这个新函数执行日志逻辑,然后执行旧的myfunc1
,它仍然以func
的名称作为闭包变量保存该函数。给定调用,请确保\uu call\uuu
方法返回一个可调用的函数(可能return func
?)感谢您提及new_func
以及为什么需要它(或不需要它,取决于用例)。对于任何感兴趣的人,我尝试调用my_func()
,无论是否使用它。没有new\u func
,对my\u func()
的第二次调用没有调用\u调用。有了它,每次调用my_func()
,都会调用\uuu call\uu
。@user3132457不完全是这样。在这两种情况下,\uuuu call\uuu
只被调用一次。但在第二个示例中,您使用在对\uuuuuu call\uuuu
的一次且唯一的调用中生成的新函数覆盖myfunc1
。这个新函数恰好执行日志逻辑,因此每次您现在调用myfunc1
时都会进行日志记录。好的,但是为什么在第二次调用myfunc1
时,没有new\u func
时不会进行日志记录呢?编辑:顺便说一下,我在\uuu call\uuu
中设置了一个断点,没有new\u func
,断点只被击中一次。为什么?@user3132457这两个问题的答案都是\uuu call\uu
只被调用一次。启动脚本时,myfunc1=logit()。\uuuu调用(myfunc1)
将执行。此后不再调用\uuuuu-call\uuuuu
。@user3132457我最近解释了装饰器的工作原理,也许你会发现它很有用。关键的一点是,decorator只在生成新函数时被调用一次。
@logit()
def myfunc1():
pass
myfunc1 = logit()(myfunc1)