2010-07-30 16 views
5

Ich arbeite an einem Projekt, das erfordert, dass ich das Containerobjekt an jedem Punkt picken kann, da wir erwarten, dass es unter externen Bedingungen ziemlich häufig versagt und in der Lage ist, dort, wo wir aufgehört haben, stattzufinden.Kann Logger nicht beizen?

ich die Python-Logging-Bibliothek bin mit ziemlich umfangreich, und alle meine Klassen starten, indem Sie einen Logger wie der Einrichtung:

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

Da ich eine Container-Klasse Beizen, hat es mehrere Schichten von Klassen in ihm, jede mit ihrer eigenen Logger-Instanz.

Jetzt, aus irgendeinem Grund, brechen diese Logger Pickle. Ich erhalte den folgenden Fehler, der weggeht, wenn ich self.logger aus allen Klassen löschen:

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

Also meine Frage ist, ob es eine Möglichkeit ist, die Sperrobjekte aus allen Loggern zu entfernen, ohne Ich muss meinen gesamten Objektbaum durchforsten, indem ich Logger lösche, die ich bei der Wiederherstellung neu erstellen muss.

Antwort

4

Sie könnten eine Klasse erstellen, die den Logger umschließt und __getstate__ und __setstate__ implementiert.

Dies wird eingefügt von http://docs.python.org/library/pickle.html. Die fh wird in einer Weise behandelt, die ähnlich zu dem, was Sie benötigen, ist.

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

Sie dill hier verwendet haben könnte, die kann Holzfäller und Schlösser beizen.

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

Sie können auch eine Klasse erstellen, die eine Eigenschaft implementiert, die den benötigten Logger zurückgibt. Jede Klasse, die von diesem "LoggerMixin" erbt, kann nun den Logger auf die gleiche Weise verwenden wie zuvor.

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

das ist eine übersehene aber nette Antwort. –

Verwandte Themen