Один декоратор для 3 разных функций
Я пишу Python API, и у меня есть одна проблема. У меня есть 3 разные функции:
func1() -> return only text
func2(name) -> return text only but takes parameter
func3(name) -> this function create a file "name".txt
Теперь у меня проблема с декоратором, я хочу создать декоратор логов, который вызывается при каждом вызове функции. Проблема в том, что я не знаю, как просто сделать это, я знаю, как создать его без параметра или одного параметра, но я понятия не имею, как создать универсальный декоратор, который будет работать для всех трех функций.
Теперь у меня есть что-то вроде этого:
def log(func):
def wrapper(name):
func(name)
log = ('write something here')
f = open('log.txt', 'a+')
f.write(log + "\n")
f.close(name)
return wrapper
2 ответа
Ваша оболочка должна принимать произвольное количество аргументов, с *args
а также **kwargs
синтаксис для захвата как позиционных, так и ключевых аргументов. Убедитесь, что вы возвращаете все, что возвращает упакованная функция:
def log(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
log = ('write something here')
with open('log.txt', 'a+') as f:
f.write(log + "\n")
return result
return wrapper
Вы, вероятно, хотите добавить в @functools.wraps
декоратор; это копирует любую документацию и другие метаданные из оригинальной упакованной функции в новую оболочку:
from functools import wraps
def log(func):
@wraps(func)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
log = ('write something here')
with open('log.txt', 'a+') as f:
f.write(log + "\n")
return result
return wrapper
И последнее, но не менее важное: вместо того, чтобы заново открывать файл журнала, взгляните на logging
модуль для обработки файлов журнала для вас.
def log(func):
def wrapper(*args, **kwds):
log = func(*args, **kwds)
f = open('log.txt', 'a+')
f.write(log + "\n")
f.close()
return wrapper
@log
def func1():
return "Called function 1"
@log
def func2(name):
return "Called function 2 with " + name
@log
def func3(name):
f = open('name.txt', 'a+')
f.write(name + " from func3\n")
f.close()
return "Called function 3 with " + name
def main():
func1()
func2("func2")
func3("func3")
if __name__ == '__main__':
main()
Log.txt становится:
Called function 1
Called function 2 with func2
Called function 3 with func3