处理一个项目,要求我能够随时挑选容器对象,因为我们希望它能够经常在外部条件下失败,并能够完全从我们中断的地方开始。
我正在广泛使用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上重新创建。
答案 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)
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>