0

I am writing python API and I have one problem. I have 3 different functions:

func1()        -> return only text
func2(name)    -> return text only but takes parameter
func3(name)    -> this function create a file "name".txt

Now I have a problem with decorator, I want to create a log decorator that is called everytime function is called. Problem is that I dont know how to simply do it, I know how to create it with no param or one param but I have no idea hot to create universal decorator that will work for all three functions.

Now i have something like this:

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
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
eMZet
  • 35
  • 1
  • 1
  • 6
  • You need to use arbitrary arguments - see e.g. http://stackoverflow.com/q/36901/3001761. Then just `return` whatever `func` gives back, functions that don't explicitly return anything return `None`. – jonrsharpe Mar 06 '16 at 14:18

2 Answers2

2

Your wrapper should accept an arbitrary number of arguments, with the *args and **kwargs syntax to capture both positional and keyword arguments. Make sure to return whatever the wrapped function returns:

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

You probably want to add in the @functools.wraps decorator; this copies across any documentation and other metadata from the original wrapped function to the new wrapper:

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

Last but not least, rather than reopening a log file yourself, take a look at the logging module to handle log files for you.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1
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 becomes:

Called function 1
Called function 2 with func2
Called function 3 with func3
sdg
  • 36
  • 2