Объект NoneType не вызывается классом декоратора - PullRequest
0 голосов
/ 12 октября 2018

Я изучаю классы декораторов, используя этот ресурс:
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

1 Ответ

0 голосов
/ 12 октября 2018

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 в качестве закрывающей переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...