Помогите с написанием декоратора
помогите пожалуйста написать декоратор по нижеуказанным условиям, не могу разобраться с кодом:
Написать декоратор, который будет логировать (записывать в лог файл) ошибки из декорируемой функции и выбрасывать их дальше.
- Формат лога: <имя функции> <параметры вызова> <тип ошибки> <текст ошибки>
- Лог файл открывать каждый раз при ошибке в режиме 'a'
def log_errors(func):
pass
- Проверить работу на следующих функциях
@log_errors
def perky(param):
return param / 0
@log_errors
def check_line(line):
name, email, age = line.split(' ')
if not name.isalpha():
raise ValueError("it's not a name")
if '@' not in email or '.' not in email:
raise ValueError("it's not a email")
if not 10 <= int(age) <= 99:
raise ValueError('Age not in 10..99 range')
lines = [
'Имя почта@mail.ru 20',
'имя почта@mail.ru 18'
.....
.....
.....
]
for line in lines:
try:
check_line(line)
except Exception as exc:
print(f'Invalid format: {exc}')
perky(param=42)
Ответы (2 шт):
def log_errors(func):
def surrogate(*args, **kwargs):
try:
return func(*args, **kwargs)
except ZeroDivisionError as z_error:
file_content1 = ('<{}> <{}> <{}> <{}>\n'.format(func.__name__, kwargs, Exception, z_error))
with open('function_errors.log', 'a', encoding='utf8') as file:
file.write(file_content1)
raise ZeroDivisionError
except ValueError as v_error:
file_content2 = ('<{}> <{}> <{}> <{}>\n'.format(func.__name__, args, Exception, v_error))
with open('function_errors.log', 'a', encoding='utf8') as file:
file.write(file_content2)
raise ValueError
return surrogate
# Проверить работу на следующих функциях
@log_errors
def perky(param):
return param / 0
@log_errors
def check_line(line):
name, email, age = line.split(' ')
if not name.isalpha():
raise ValueError("it's not a name")
if '@' not in email or '.' not in email:
raise ValueError("it's not a email")
if not 10 <= int(age) <= 99:
raise ValueError('Age not in 10..99 range')
lines = [
'Имя почта@mail.ru 20',
'имя почта@mail.ru 18'
.....
.....
.....
]
for line in lines:
try:
check_line(line)
except Exception as exc:
print(f'Invalid format: {exc}')
perky(param=42)
Для этого есть готовая библиотека - Polog. Предлагаемый там логгер универсален, его можно использовать как обычную функцию или в качестве декоратора.
Установка библиотеки:
$ pip install polog
И простой пример применения:
from polog import log, config, file_writer
config.add_handlers(file_writer())
@log("my message")
def function(a, b):
return a / b
function(1, 3)
В консоли будет что-то похожее (актуально для версии 0.0.16):
[2022-10-31 22:43:58.321594] | 1 | SUCCESS | AUTO | "my message" | where: __main__.function() | time of work: 0.00001192 sec. | input variables: 1 (int), 3 (int) | result: 0.3333333333333333 (float)
Теперь попробуем спровоцировать ошибку, вызовем функцию с аргументами, которые приведут к делению на 0:
function(1, 0)
И на этот раз в консоли будет что-то вот такое:
[2022-10-31 22:46:03.772676] | 2 | ERROR | AUTO | "my message" | where: __main__.function() | time of work: 0.00001192 sec. | input variables: 1 (int), 0 (int) | local variables: a = 1 (int), b = 0 (int) | exception: ZeroDivisionError("division by zero") | traceback: return a / b (".../some_file.py", line 7, in function)
Более подробно о возможностях библиотеки читайте в документации (на русском).