关于python:简单的日志记录对象

Simple logging object

我有一些python模块,它有一个类ModuleClass,我不能修改这个类。

现在,我希望能够代理方法调用并添加某些日志记录功能。我想这应该通过转发对象和相应的代理(following Effective Java, Item 16)来完成。

我提出的python伪代码如下。

(对不起,我对python很不在行,如果您能指出这里的错误,我将不胜感激)。

1
2
3
4
5
6
7
8
# This is what I've got in my module and this code cannot be changed.
class ModuleClass(object):
    def method1(self):
        # Some implementation
        pass()
    def method2(self):
        # Some implementation
        pass()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Simple forwarding proxy to avoid the situation described in Effective Java, I16

# However, in Java this class would usually be extending the interface, not
# inheriting 'ModuleClass' (I'm confused and don't know how to do the same
# in python).

class ForwardingModuleClass(ModuleClass):
    # 'proxifiedObject' is
    def __init__(self, proxifiedObject):
        self.proxifiedObject = proxifiedObject

    # Overriding the first method
    def method1(self):
        return self.proxifiedObject.method1()

    # Same for method2...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class LoggingModuleClass(ForwardingModuleClass):
    # 'classThatActuallyDoesStuff' should be an instance of 'ModuleClass'.
    def __init__(self, classThatActuallyDoesStuff):
        # Sorry for my bad knowledge of python syntax, but
        # I assume I can initialize the superclass here using
        # the supplied 'ModuleClass' instance.
        super(classThatActuallyDoesStuff)

    # Overriding the first method.
    def method1(self):
        print("Yay! This 'method1' really logs something!")
        return super.method1()

    # Overriding the second method.
    def method2(self):
        print("Yay!!!! This 'method2' also does something cool!")
        return super.method2()

现在,我想,适当地写下,这会起作用,我将拥有我的初始ModuleClass的日志代理。

如果有错误或这不是Python,请指出它。

另外,我怀疑使用decorators可以很容易地做到这一点,但不幸的是,我无法找到合适的方法,我不知道如果ModuleClass已经有了一些方法修饰器会发生什么。

你也能帮我吗?


如果您真的想要一个包装器,那么只需编写它,不需要子类和中间类。

1
2
3
4
5
6
7
8
9
10
11
class LoggingFoo(object):
    def __init__(self, *args, **kwargs):
        self.obj = Foo(*args, **kwargs)

    def method1(self):
        # ...
        return self.obj.method1()

    def method2(self):
        # ...
        return self.obj.method2()


直接子类moduleClass如何?

1
2
3
4
5
6
7
8
9
10
11
12
13
import logging

logger=logging.getLogger(__name__)

class LoggingModuleClass(ModuleClass):
    def method1(self):
        logger.info("Yay! This 'method1' really logs something!")
        return super(LoggingModuleClass,self).method1()
    def method2(self):
        logger.info("Yay! This 'method2' also does something cool!")
        return super(LoggingModuleClass,self).method2()

logging.basicConfig(level=logging.DEBUG)

(我添加了代码来显示记录python方式的基本设置)。


如果您正在寻找一个decorator解决方案,那么您应该看看本文的答案:python decorator使函数忘记它属于一个类。

您表示希望避免"不需要的消息"(在method1调用method2的情况下),那么我建议您选择cat plus提供的解决方案,否则我将选择运算符。