Monkeypatching logging.Logger - 参数如何工作?

时间:2014-07-07 03:28:43

标签: python logging monkeypatching

我有一个我编写的日志类,我喜欢使用它。它看起来像这样:

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的参数修复了错误,但我很困惑:为什么selfself.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}}

这里发生了什么?

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)