Подтвердить что ты не робот

Как __enter__ и __exit__ работают в классах декоратора Python?

Я пытаюсь создать класс декоратора, который подсчитывает, сколько раз вызывается функция, но я получаю сообщение об ошибке:

    "TypeError: __exit__() takes exactly 1 argument (4 given)"

и я действительно не знаю, как я даю ему четыре аргумента. Мой код выглядит следующим образом:

class fcount2(object):
    __instances = {}
    def __init__(self, f):
        self.__f = f
        self.__numcalls = 0
        fcount2.__instances[f] = self

    def __call__(self, *args, **kwargs):
        self.__numcalls += 1
        return self.__f(*args, **kwargs)

    def __enter__(self):
        return self

    def __exit__(self):
        return self

    @staticmethod
    def count(f):
        return fcount2.__instances[self.__f].__numcalls


@fcount2
def f(n):
    return n+2

for n in range(5):
    print f(n)   
print 'f count =',f.count

def foo(n):
    return n*n

with fcount2(foo) as g:
    print g(1)
    print g(2)
print 'g count =',g.count
print 'f count =',f.count

with fcount2(f) as g:
    print g(1)
    print g(2)
print 'g count =',g.count
print 'f count =',f.count

with f:
    print f(1)
    print g(2)
print 'g count =',g.count
print 'f count =',f.count

Есть ли какие-то другие параметры, которые я должен (или не должен) переходить в функцию def exit? Любые советы или идеи будут оценены.

В стороне, моя строка кода, в которой указано "print" f count = ', f.count ", как представляется, выводит адрес памяти, а не значение, но это целая проблема.

4b9b3361

Ответ 1

метод __exit__() должен принимать информацию об исключениях, которые появляются в блоке with:. См. здесь.

Следующая модификация вашего кода работает:

def __exit__(self, exc_type, exc_value, traceback):
    if exc_type is not None:
        print exc_type, exc_value, traceback
        # return False # uncomment to pass exception through

    return self

Затем вы можете попробовать создать исключение в одном из ваших блоков with:, и оно будет найдено в __exit__().