我有一个关于登录Python的问题。情况如下:我的应用程序有一个全局上下文对象(单例),其中包括一个记录器对象。所有需要使用日志记录的类都可以从上下文中获取此全局记录器对象,并使用它来输出消息。
但是,一些持有此类记录器的对象需要保存到pickle文件中。当pickle对象具有对打开的FileHandler的引用时,保存到pickle不起作用,在这种情况下是对象的情况,因为它们持有记录器并因此保持打开文件处理程序。
现在,我可以在酸洗前删除所有文件处理程序,如下所示:
def closeLogFile(self):
handlers = self.logger.handlers[:]
for handler in handlers:
handler.close()
self.logger.removeHandler(handler)
但是这会产生副作用,即对于仍然保存对全局记录器的引用的所有其他对象,也会删除日志处理程序。
什么是更好的方法来允许全局日志记录到同一个文件并允许单个类的酸洗?
提前感谢一百万。
干杯,
马丁
答案 0 :(得分:1)
如果您使用dill
代替pickle
,则可能适用于您。 dill
可以处理对FileHandles
的引用,并具有适用于不同用例的变体。这是默认设置:
>>> import dill
>>> import logging
>>> l = logging.Logger('foo')
>>>
>>> class Foo(object):
... def __init__(self, x):
... self.logger = l
... self.x = x
... self.other = logging.Logger('bar')
...
>>> f = Foo(4)
>>> f.logger
<logging.Logger object at 0x1094d3210>
>>> f.other
<logging.Logger object at 0x1094d34d0>
>>>
>>> f_ = dill.dumps(f)
>>> _f = dill.loads(f_)
>>>
>>> _f.logger
<logging.Logger object at 0x1094f1c90>
>>> _f.other
<logging.Logger object at 0x1094f1b50>
请注意,未标记的Logger
实例与原始实例的实例不同,但它们仍指向相同的日志。实际上,您获得了一个新类__main__.Foo
,因为默认情况下dill
会对类对象进行pickle而不是pickling引用。此行为应扩展到不同的类 - 基本上旧的__main__.Foo
和新的__main__.Foo
已经演示。