简单的日志对象
我有一个 python
模块,这个模块里有一个类叫 ModuleClass
,但是我不能修改这个类。
现在,我想对这个类的方法调用进行 代理,并添加一些日志记录的功能。我想这应该通过转发对象和相应的代理来实现 (参考《Effective Java》,第16条)
。
我想出的 python
伪代码如下。
(抱歉,我的 python
技术真的很差,如果你能指出这里的错误,我会很感激)。
# 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()
# 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...
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
已经有一些方法装饰器会发生什么。
你能在这方面帮我吗?
3 个回答
1
如果你在寻找装饰器的解决方案,可以看看这个帖子里的回答:Python 装饰器让函数忘记它属于一个类
你提到想要避免“多余的信息”(比如 method1 调用 method2 的时候),那么我建议你选择 Cat Plus Plus 提供的解决方案,否则我会推荐使用运算符。
2
直接继承ModuleClass怎么样:
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的方式进行基本的日志记录设置。)
2
如果你真的想要一个包装器,那就直接写一个,不需要继承其他类或者中间类。
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()