Один декоратор для 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
Другие вопросы по тегам