如何对日志记录器进行序列化?

11 投票
5 回答
14487 浏览
提问于 2025-04-16 02:05

我正在做一个项目,需要能够在任何时候将容器对象保存下来,因为我们预计它会因为外部条件而频繁出错,并且希望能够完全从上次中断的地方继续。

我在项目中大量使用了Python的日志库,我的所有类一开始都会设置一个日志记录器,像这样:

class foo:
   def __init__(self):
       self.logger = logging.getLogger("package.foo")

由于我正在保存一个容器类,它里面有好几层不同的类,每个类都有自己的日志记录器实例。

但是,不知道为什么,这些日志记录器导致了保存失败。我遇到了以下错误,如果我把所有类中的self.logger删掉,这个错误就消失了:

Can't pickle 'lock' object: <thread.lock object at ... >

所以我想问,有没有办法在不遍历整个对象树删除日志记录器的情况下,去掉所有日志记录器中的锁对象?因为这样的话,我在恢复对象时还得重新创建这些日志记录器。

5 个回答

7

Python 3.7的新特性 (bpo30520)

现在,Logger可以像许多其他对象一样被“腌制”(也就是可以被保存和恢复)。

import pickle
import logging
log = logging.getLogger(__name__)
logger_pickle = pickle.dumps(log)

# and of coarse, to load:
log = pickle.loads(logger_pickle)
18

你还可以创建一个类,这个类里面有一个属性,可以返回你需要的日志记录器。任何从这个“LoggerMixin”类继承的类,现在都可以像之前一样使用这个日志记录器。

class LoggerMixin():
    @property
    def logger(self):
        component = "{}.{}".format(type(self).__module__, type(self).__name__)
        return logging.getLogger(component)

class Foo(LoggerMixin):
    def __init__(self):
        self.logger.info("initialize class")

    def bar(self):
        self.logger.info("execute bar")
2

在这里找到一个非常相似的问题,里面有个答案对我有效:

如何在Python中阻止属性被序列化

补充:我用了这个答案:如何在Python中阻止属性被序列化

撰写回答