2013-03-15 23 views
13

Tôi có một ứng dụng phải chạy một số lần chạy mô phỏng. Tôi muốn thiết lập một cơ chế đăng nhập, nơi tất cả các logrecords được đăng nhập vào một general.log, và tất cả các bản ghi cho một chạy mô phỏng đi đến run00001.log, .... Đối với điều này tôi đã định nghĩa một lớp Run. trong __init__() một tập tin mới được thêm vào cho runlog.python không phát hành filehandles để logfile

Vấn đề là các logfiles cho các hoạt động không bao giờ được phát hành, do đó, sau khi một số chạy các tay cầm có sẵn đã cạn kiệt và chạy bị treo.

tôi đã thiết lập một số thói quen để kiểm tra điều này như sau

chính thói quen

import Model 
try: 
    myrun = Model.Run('20130315150340_run_49295') 
    ha = raw_input('enter') 
    myrun.log.info("some info") 
except: 
    traceback.print_exc(file=sys.stdout) 

ha = raw_input('enter3') 

Lớp Chạy được định nghĩa trong mô-đun mẫu như sau

import logging 
class Run(object): 

    """ Implements the functionality of a single run. """ 
    def __init__(self, runid): 
     self.logdir="." 
     self.runid   = runid 
     self.logFile  = os.path.join(self.logdir , self.runid + '.log') 
     self.log   = logging.getLogger('Run'+self.runid) 
     myformatter   = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s') 
     myhandler  = logging.FileHandler(self.logFile) 
     myhandler.setLevel(logging.INFO) 
     myhandler.setFormatter(myformatter) 
     self.log.addHandler(myhandler) 

Sau đó, tôi sử dụng chương trình thám hiểm quá trình để làm theo các filehandlers. Và tôi thấy các runlog xuất hiện, nhưng không bao giờ biến mất.

Có cách nào để tôi có thể thực hiện việc này không?

+1

Tại sao không loại bỏ các xử lý một lần nữa khi kết thúc chạy? Có lẽ bạn có thể móc vào sự kiện đó? –

+0

Bất kỳ lời khuyên nào về cách thực hiện điều đó? Tôi đã thử với việc xác định self.log.removeHandler (myhandler) trong __del __(), thậm chí bằng cách gọi destructor một cách rõ ràng (myrun .__ del __()). Tôi cũng đã thử bằng cách xác định __exit __() và sử dụng câu lệnh with, như được đề xuất để mở tệp tin bằng mở. Nhưng không thành công cho đến nay. –

+1

Bạn cũng cần gọi '.close()' trên trình xử lý tệp. 'self.log.handlers [0] .đóng()' là đủ, thực sự. –

Trả lời

32

Bạn cần gọi số .close() trên trình xử lý tệp.

Khi lớp Run bạn hoàn thành, hãy gọi:

handlers = self.log.handlers[:] 
for handler in handlers: 
    handler.close() 
    self.log.removeHandler(handler) 
+0

Sẽ không '[:]' tạo một bản sao của danh sách trình xử lý? –

+0

@VasilisLemonidis: vâng, đó là vấn đề. Bạn không nên lặp qua danh sách và xóa các phần tử khỏi danh sách, bạn sẽ kết thúc việc bỏ qua các phần tử. –

+0

@VasilisLemonidis: cách thay thế có thể là xử lý các phần tử ngược lại: 'cho trình xử lý đảo ngược (self.log.handlers): ...'. –

Các vấn đề liên quan