I have a logging class that I've written that I like to use. It looks like this:
class EasyLogger(object):
SEP = " "
def __init__(self, logger=logging.getLogger(__name__)):
self.logger = logger
def _format_str(self, *args):
return self.SEP.join([str(a) for a in args])
def debug(self, *args):
self.logger.debug(self._format_str(*args))
.... repeated for the other logging methods, like info, warning, etc....
def __getattr__(self, name):
return getattr(self.logger, name)
This gives me syntax like:
LOG.debug("some_variable: ", some_variable)
which I like. I don't want to inherit from logging.Logger
because composition is better than inheritance and I don't really want to mess around with builtin classes like that.
My format string looks like:
LOGGING_FMT = "<%(filename)s:%(lineno)s(%(levelname)s) - %(funcName)s() >"\
"%(message)s"
but this doesn't work, because the line numbers and function name always report as something inside easylogger.py
rather than the calling function.
I've fixed this issue by following this fantastic answer and monkeypatching the findCaller
method of EasyLogger.logger
, which looks like this:
def __init__(self, logger=logging.getLogger(__name__)):
self.logger = logger
# Ugly, ugly, ugly dirty hack to fix line numbers
self.logger.findCaller = find_caller_monkeypatch
This works, but I'm confused. I originally defined find_caller_monkeypatch
with the following signature:
def find_caller_monkeypatch(self):
(the body of the function is copy+pasted from the answer that's linked). However, this causes an error:
File "/usr/lib64/python2.7/logging/__init__.py", line 1262, in _log
fn, lno, func = self.findCaller()
TypeError: find_caller_monkeypatch() takes exactly 1 argument (0 given)
Removing self
as an argument to find_caller_multipatch
fixes the error, but I'm confused: why isn't find_caller_monkeypatch
getting self
as an argument when it's called as self.findCaller()
? Do methods only get self
as a parameter if they're defined inside of the class?
The following snippet is a smaller example of the same issue:
In [7]: class Foo(object):
...: def say_hi(self):
...: print "Hello World"
...:
In [8]: def say_bye_self(self): print "Goodbye world"
In [9]: def say_bye(): print "Goodbye world"
In [10]: foo = Foo()
In [11]: foo.say_hi()
Hello World
In [12]: foo.say_hi = say_bye_self
In [13]: foo.say_hi()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-13-10baea358e0b> in <module>()
----> 1 foo.say_hi()
TypeError: say_bye_self() takes exactly 1 argument (0 given)
In [14]: foo.say_hi = say_bye
In [15]: foo.say_hi()
Goodbye world
What's going on here?
You can Monkeypatch on the class
Foo.say_hi = say_bye_self
foo = Foo()
foo.say_hi()
Or you can Monkeypatch an instance
import types
foo.say_hi = types.MethodType(say_bye_self, foo)
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.