2010-07-30 50 views
5

处理一个需要我可以随时腌制容器对象的项目,因为我们期望它经常在外部条件下失败并且能够有状态地从我们离开的地方拿起。不能泡菜记录器?

我使用Python记录库相当广泛,和我所有的班开始通过建立一个记录器,如:

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

由于我酸洗一个容器类,它具有类几层在它内部,每个都有自己的记录器实例。

现在,出于某种原因,这些伐木工正在破坏腌菜。我收到以下错误,它就会消失,如果我从所有的类删除self.logger:

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

所以我的问题是,是否有某种方式来删除所有记录仪锁定的对象,而不不得不缓冲通过我的整个对象树删除记录器,我将不得不在unpickle重新创建。

回答

4

您可以创建一个包装记录器并实现__getstate____setstate__的类。

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

#!/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 
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> 
4

你也可以创建一个实现返回所需的记录属性的类。从此“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") 
+0

这是一个被忽视但很好的回应。 – 2017-11-05 18:57:20