У меня есть класс ведения журнала, который я написал, и мне нравится его использовать. Это выглядит так:
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)
Это дает мне синтаксис вроде:
LOG.debug("some_variable: ", some_variable)
который я хотел. Я не хочу наследовать от logging.Logger
, потому что композиция лучше, чем наследование, и я действительно не хочу возиться с подобными встроенными классами.
Моя строка формата выглядит так:
LOGGING_FMT = "<%(filename)s:%(lineno)s(%(levelname)s) - %(funcName)s() >"\
"%(message)s"
но это не работает, потому что номера строк и имя функции всегда сообщают что-то внутри easylogger.py
, а не вызывающей функции.
Я исправил эту проблему, следуя этому фантастический ответ и исправление findCaller
метода EasyLogger.logger
, который выглядит так:
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
Это работает, но я в замешательстве. Первоначально я определил find_caller_monkeypatch
со следующей подписью:
def find_caller_monkeypatch(self):
(тело функции копируется + вставляется из связанного ответа). Однако это вызывает ошибку:
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)
Удаление self
в качестве аргумента для find_caller_multipatch
исправляет ошибку, но я запутался: почему find_caller_monkeypatch
не получает self
в качестве аргумента, когда он вызывается как self.findCaller()
? Получают ли методы self
в качестве параметра только в том случае, если они определены внутри класса?
Следующий фрагмент представляет собой меньший пример той же проблемы:
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
Что тут происходит?