我有一个我编写的日志类,我喜欢使用它。它看起来像这样:
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
内而不是调用函数中报告。
我已修复此问题,方法是按照this精彩回答并对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
作为参数吗?
以下代码段是同一问题的较小示例:
{{1}}
这里发生了什么?
答案 0 :(得分:2)
你可以在课堂上使用Monkeypatch
Foo.say_hi = say_bye_self
foo = Foo()
foo.say_hi()
或者你可以Monkeypatch一个实例
import types
foo.say_hi = types.MethodType(say_bye_self, foo)