如何腌制伐木工人?

时间:2010-07-30 21:22:08

标签: python logging pickle

处理一个项目,要求我能够随时挑选容器对象,因为我们希望它能够经常在外部条件下失败,并能够完全从我们中断的地方开始。

我正在广泛使用python日志库,我的所有类都是通过设置一个记录器来开始的:

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

由于我正在挑选一个容器类,因此它里面有几层类,每个类都有自己的记录器实例。

现在,出于某种原因,这些记录器正在破坏Pickle。我收到以下错误,如果我从所有类中删除self.logger,它就会消失:

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

所以我的问题是,是否有某种方法可以从所有记录器中删除锁定对象,而不必通过整个对象树删除记录器,我将不得不在unpickle上重新创建。

5 个答案:

答案 0 :(得分:10)

您还可以创建一个实现返回所需记录器的属性的类。每一个继承自这个&#34; LoggerMixin&#34;现在可以像以前一样使用记录器了。

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")

答案 1 :(得分:4)

您可以创建一个包装记录器并实现__getstate__和的类 __setstate__

这是从http://docs.python.org/library/pickle.html粘贴的。 fh的处理方式可能类似于您的需要。

#!/usr/local/bin/python

class TextReader:
    """Print and number lines in a text file."""
    def __init__(self, file):
        self.file = file
        self.fh = open(file)
        self.lineno = 0

    def readline(self):
        self.lineno = self.lineno + 1
        line = self.fh.readline()
        if not line:
            return None
        if line.endswith("\n"):
            line = line[:-1]
        return "%d: %s" % (self.lineno, line)

    def __getstate__(self):
        odict = self.__dict__.copy() # copy the dict since we change it
        del odict['fh']              # remove filehandle entry
        return odict

    def __setstate__(self, dict):
        fh = open(dict['file'])      # reopen file
        count = dict['lineno']       # read from file...
        while count:                 # until line count is restored
            fh.readline()
            count = count - 1
        self.__dict__.update(dict)   # update attributes
        self.fh = fh                 # save the file object

答案 2 :(得分:2)

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

How to stop attributes from being pickled in Python

编辑:使用了这个答案:How to stop attributes from being pickled in Python

答案 3 :(得分:2)

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)

答案 4 :(得分:1)

你可以在这里使用dill,这可以腌制记录器和锁。

>>> class foo:
...    def __init__(self):
...        self.logger = logging.getLogger("package.foo")
... 
>>> import dill
>>> import logging
>>> 
>>> f = foo()
>>> _f = dill.dumps(f)  
>>> f_ = dill.loads(_f)
>>> f_.logger
<logging.Logger object at 0x110b1d250>