2010-07-30 27 views
5

Làm việc trên một dự án yêu cầu tôi có thể chọn đối tượng chứa tại bất kỳ thời điểm nào, vì chúng tôi hy vọng nó không hoạt động thường xuyên ở bên ngoài và có thể nhận được nơi chúng tôi rời đi.Bạn không thể hái logger?

Tôi đang sử dụng thư viện khai thác gỗ trăn khá rộng rãi, và tất cả các lớp học của tôi bắt đầu bằng cách thiết lập một logger như:

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

Kể từ khi tôi đang tẩy một lớp container, nó có một số lớp của các lớp học bên trong nó, mỗi người có cá thể logger riêng của họ.

Bây giờ, vì một số lý do, những người đăng nhập này đang phá vỡ Pickle. Tôi nhận được lỗi sau, sẽ biến mất nếu tôi xóa self.logger khỏi tất cả các lớp:

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

Vì vậy, câu hỏi của tôi là có hay không có cách nào đó để xóa các đối tượng khóa khỏi tất cả nhật ký mà không phải recurse thông qua toàn bộ cây đối tượng của tôi xóa logger mà tôi sẽ phải tạo lại trên unpickle.

Trả lời

2

Tìm thấy một câu hỏi rất giống nhau ở đây, với một câu trả lời mà làm việc cho tôi:

How to stop attributes from being pickled in Python

chỉnh sửa: sử dụng câu trả lời này: How to stop attributes from being pickled in Python

+1

Có lẽ bạn có thể liên kết tới (hoặc trích dẫn) câu trả lời chính xác mà bạn đã sử dụng? (Có hai) Có nút "liên kết" bên dưới bất kỳ câu trả lời nào bạn có thể nhấp vào cho url. – PriceChild

4

Bạn có thể tạo lớp học bao gồm trình ghi nhật ký và triển khai __getstate____setstate__.

Điều này được dán từ http://docs.python.org/library/pickle.html. fh được xử lý theo cách có thể tương tự với những gì bạn cần.

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

Bạn có thể đã sử dụng dill đây, mà có thể pickle loggers và ổ khóa.

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

Bạn cũng có thể tạo lớp học triển khai thuộc tính trả về trình ghi nhật ký cần thiết. Mỗi lớp mà kế thừa từ "LoggerMixin" này bây giờ có thể sử dụng logger giống như cách bạn đang sử dụng nó trước đây.

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

đây là một phản ứng bị bỏ qua nhưng tốt đẹp. –