Подсчет количества вызовов функций с помощью декоратора
Парни помогите разобраться в декораторе, дали домашку для ознакомления но очень тяжко идет это все.
Написать декоратор call_times, который будет принимать в качестве параметра file_name, считать количество вызовов функций и записывать в файл в формате f'{func_name} была вызвана {count} раза.\n'
Пример:
@call_times('foo.txt')
def foo():
pass
@call_times('foo.txt')
def boo():
pass
@call_times('calls.txt')
def doo():
pass
foo()
boo()
foo()
foo()
boo()
doo()
Файл foo.txt:
foo была вызвана 3 раза
boo была вызвана 2 раза
Файл calls.txt:
doo была вызвана 1 раза
Все работает как надо, всем спасибо ребята.
counter = {}
text = 'Function {} was called {} times.\n'
def call_times(file_name):
def inner(func):
def wrapper():
wrapper.count += 1
counter[func.__name__] = wrapper.count
with open(file_name, 'w') as f:
for func_name, quantity in counter.items():
f.write(text.format(func_name, quantity))
return func()
wrapper.count = 0
return wrapper
return inner
@call_times('foo.txt')
def foo():
pass
@call_times('foo.txt')
def boo():
pass
@call_times('calls.txt')
def doo():
pass
for i in range(5):
foo()
for i in range(10):
boo()
dict.clear(counter)
for i in range(15):
doo()
Ответы (1 шт):
return func() у вас завершает работу wrapper(), до записи в файл дело не доходит. Нужно сначала записать в файл, потом уже выходить из функции через return:
count = 0
def call_times(file_name):
def inner(func):
def wrapper():
global count
count += 1
with open(file_name, 'a') as f:
f.write(f'{func.__name__} была вызвана {count} раза.\n')
return func()
return wrapper
return inner
Но чтобы у вас считались отдельно вызовы каждой функции, а не считало общее количество вызовов, действительно нужно использовать словарь, в котором будут считаться вызовы каждой конкретной функции (ключ - функция, значение - количество вызовов):
from collections import defaultdict
counts = defaultdict(int)
def call_times(file_name):
def inner(func):
def wrapper():
counts[func] += 1
with open(file_name, 'a') as f:
f.write(f'{func.__name__} была вызвана {counts[func]} раза.\n')
return func()
return wrapper
return inner