I'm trying to make a decorator for logging purposes. I try to increment the name of a log when the same decorator is called inside sub-function but fail to have a correct input. I also have some difficulty understanding my actual output.
import datetime
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
wrapper.log_name += "." + func.__name__
start = datetime.datetime.now()
func(*args, **kwargs)
duration = datetime.datetime.now() - start
print(f"{wrapper.log_name }: {duration}")
wrapper.log_name = "test"
return wrapper
@log
def main_function():
other_function()
@log
def other_function():
print("i'm in the other function")
if __name__ == '__main__':
main_function()
main_function()
I got:
i'm in the other function
**test.other_function:** 0:00:00.000007
test.main_function: 0:00:00.000021
i'm in the other function
test.other_function.other_function: 0:00:00.000001
test.main_function.main_function: 0:00:00.000004
But I expected:
i'm in the other function
test.main_function.other_function: 0:00:00.000007
test.main_function: 0:00:00.000021
i'm in the other function
test.main_function.other_function: 0:00:00.000001
test.main_function: 0:00:00.000004
Do you know how to solve this?
Used inspect
library to get calling function info from the stack
.
* Added other_function2
just to check.
import datetime
import functools
import inspect
def log(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
# get previous callings from the stack
previous_callings = []
stack = inspect.stack()
for i in range(2, len(stack), 2):
if stack[i][3] != stack[0][3]: break
previous_callings.append(stack[i - 1][3])
start = datetime.datetime.now()
func(*args, **kwargs)
duration = datetime.datetime.now() - start
to_print = ['test'] + previous_callings[::-1] + [func.__name__]
print(f"{'.'.join(to_print)}: {duration}")
return wrapper
@log
def main_function():
other_function()
@log
def other_function():
print("i'm in the other function")
other_function2()
@log
def other_function2():
print("i'm in the other function 2")
if __name__ == '__main__':
main_function()
main_function()
Gives Output (Didn't bother to change the time format...)
i'm in the other function
i'm in the other function 2
test.main_function.other_function.other_function2: 0:00:00
test.main_function.other_function: 0:00:00
test.main_function: 0:00:00
i'm in the other function
i'm in the other function 2
test.main_function.other_function.other_function2: 0:00:00
test.main_function.other_function: 0:00:00
test.main_function: 0:00:00
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.