If you are looking for a scalable way to log function calls - I would suggest a decorator in that style
import logging
from functools import wraps
logging.basicConfig(level=logging.DEBUG)
def logging_wrapper(func):
@wraps(func)
def logging_inner(*args, **kwargs):
kwargs_formatted = ['{}={}'.format(k, repr(v)) for k, v in kwargs.items()]
call_line = 'Func call: {}({})'.format(func.__name__,
', '.join([repr(v) for v in args] + kwargs_formatted))
try:
res = func(*args, **kwargs)
logging.debug('{} - returns {}'.format(call_line, repr(res)))
return res
except Exception as exc:
logging.exception(call_line + ' caused exception!')
return logging_inner
Now, decorate function of your choice
@logging_wrapper
def add(x, y):
return x + y
Shall we test?
>>> add(1, 4)
DEBUG:root:Func call: add(1, 4) - returns 5
5
>>> add(1, '4')
ERROR:root:Func call: add(1, '4') caused exception!
Traceback (most recent call last):
File "<stdin>", line 8, in logging_inner
File "<stdin>", line 3, in add
TypeError: unsupported operand type(s) for +: 'int' and 'str'
But what about named arguments?
>>> @logging_wrapper
... def add(first, second=None):
... return first + second
...
>>> add(1,4)
DEBUG:root:Func call: add(1, 4) - returns 5
5
>>> add(1, second=4)
DEBUG:root:Func call: add(1, second=4) - returns 5
5
>>> add(1, second='4')
ERROR:root:Func call: add(1, second='4') caused exception!
Traceback (most recent call last):
File "<stdin>", line 8, in logging_inner
File "<stdin>", line 3, in add
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>>