正如马丁(Martijn)指出的那样,事情有时会改变。但是,由于您使用的是Python
2(迭代器已将其放弃),因此如果您不介意猴子修补日志记录,则以下代码将起作用:
from functools import wrapsimport loggingclass ArgLogger(object): """ Singleton class -- will only be instantiated once because of the monkey-patching of logger. """ singleton = None def __new__(cls): self = cls.singleton if self is not None: return self self = cls.singleton = super(ArgLogger, cls).__new__(cls) self.pre_location = None # Do the monkey patch exactly one time def findCaller(log_self): self.pre_location, pre_location = None, self.pre_location if pre_location is not None: return pre_location return old_findCaller(log_self) old_findCaller = logging.Logger.findCaller logging.Logger.findCaller = findCaller return self def log_args(self, logger, level=logging.DEBUG): """Decorator to log arguments passed to func.""" def inner_func(func): co = func.__pre__ pre_loc = (co.co_filename, co.co_firstlineno, co.co_name) @wraps(func) def return_func(*args, **kwargs): arg_list = list("{!r}".format(arg) for arg in args) arg_list.extend("{}={!r}".format(key, val) for key, val in kwargs.iteritems()) msg = "{name}({arg_str})".format(name=func.__name__, arg_str=", ".join(arg_list)) self.pre_location = pre_loc logger.log(level, msg) return func(*args, **kwargs) return return_func return inner_funclog_args = ArgLogger().log_argsif __name__ == "__main__": logger = logging.getLogger(__name__) handler = logging.StreamHandler() fmt = "%(asctime)s %(levelname)-8.8s [%(name)s:%(lineno)4s] %(message)s" handler.setFormatter(logging.Formatter(fmt)) logger.addHandler(handler) logger.setLevel(logging.DEBUG) @log_args(logger) def foo(x, y, z): pass class Bar(object): @log_args(logger) def baz(self, a, b, c): pass def test_regular_log(): logger.debug("Logging without ArgLog still works fine") foo(1, 2, z=3) foo(1, 2, 3) foo(x=1, y=2, z=3) bar = Bar() bar.baz(1, c=3, b=2) test_regular_log()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)