Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ';非类型';对象不能用装饰器类调用_Python_Class_Decorator_Python Decorators - Fatal编程技术网

Python ';非类型';对象不能用装饰器类调用

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)

我正在学习使用此资源的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)
        # 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)