2011-09-20 9 views
29

मैं पायथन के लॉगिंग सिस्टम के साथ खेल रहा हूं। एक लूप में लॉगर ऑब्जेक्ट से हैंडलर को हटाते समय मैंने एक अजीब व्यवहार देखा है। अर्थात्, मेरे लूप के लिए सभी एक हैंडलर को हटा देता है। .removeHandler पर अतिरिक्त कॉल अंतिम हैंडलर को आसानी से हटा देता है। कॉल के दौरान कोई त्रुटि संदेश जारी नहीं किया जाता है। के रूप में देखा जा सकता है,पायथन के लॉगिंग लॉगर्स से हैंडलर को हटाकर

import logging 
import sys 
logging.basicConfig() 
dbg = logging.getLogger('dbg') 
dbg.setLevel(logging.DEBUG) 

testLogger = logging.getLogger('mylogger') 
sh = logging.StreamHandler(sys.stdout) 
fh = logging.FileHandler('mylogfile.log') 
dbg.debug('before adding handlers: %d handlers'%len(testLogger.handlers)) 
testLogger.addHandler(fh) 
testLogger.addHandler(sh) 

dbg.debug('before removing. %d handlers: %s'%(len(testLogger.handlers), 
               str(testLogger.handlers))) 
for h in testLogger.handlers: 
    dbg.debug('removing handler %s'%str(h)) 
    testLogger.removeHandler(h) 
    dbg.debug('%d more to go'%len(testLogger.handlers)) 

#HERE I EXPECT THAT NO HANDLER WILL REMAIN  
dbg.debug('after removing: %d handlers: %s'%(len(testLogger.handlers), 
               str(testLogger.handlers))) 
if len(testLogger.handlers) > 0: 
    #Why is this happening? 
    testLogger.removeHandler(testLogger.handlers[0]) 
dbg.debug('after manually removing the last handler: %d handlers'%len(testLogger.handlers))  

मैं उम्मीद करते हैं कि पाश के अंत में कोई संचालकों testLogger वस्तु में रहेगा लेकिन .removeHandler को आखिरी कॉल जाहिरा तौर पर विफल रहता है,:

यह परीक्षण कोड है नीचे उत्पादन। फिर भी इस फ़ंक्शन के लिए अतिरिक्त कॉल हैंडलर को अपेक्षित के रूप में हटा देता है। यहाँ आउटपुट है:

DEBUG:dbg:before adding handlers: 0 handlers 
DEBUG:dbg:before removing. 2 handlers: [<logging.FileHandler instance at 0x021263F0>, <logging.StreamHandler instance at 0x021262B0>] 
DEBUG:dbg:removing handler <logging.FileHandler instance at 0x021263F0> 
DEBUG:dbg:1 more to go 
DEBUG:dbg:after removing: 1 handlers: [<logging.StreamHandler instance at 0x021262B0>] 
DEBUG:dbg:after manually removing the last handler: 0 handlers 

ज्यादा दिलचस्प है, अगर मैं के बाद एक, पाश काम करता है की उम्मीद है और कोई संचालकों पाश के अंत में testLogger वस्तु में रहते हैं के रूप में के साथ मूल पाश की जगह।

while len(testLogger.handlers) > 0: 
    h = testLogger.handlers[0] 
    dbg.debug('removing handler %s'%str(h)) 
    testLogger.removeHandler(h) 
    dbg.debug('%d more to go'%len(testLogger.handlers)) 

क्या इस व्यवहार बताते हैं: यहाँ संशोधित पाश है? क्या यह बग है या मैं कुछ भूल गया हूं?

+1

'(testLogger.handlers)' – sherpya

उत्तर

64

यह लॉगर-विशिष्ट व्यवहार नहीं है। कभी भी उत्परिवर्तित (तत्वों को सम्मिलित/निकालें) सूची जो आप वर्तमान में चालू कर रहे हैं। यदि आपको आवश्यकता है, तो एक प्रति बनाएं। इस मामले में testLogger.handlers = [] चाल चलाना चाहिए।

+4

hehehe: मैं स्थापित करने की स्पष्ट समाधान याद किया सूची []। मुझे लगता है कि मुझे और कॉफी चाहिए –

3

आप उन सब (the tip @CatPlusPlus के लिए धन्यवाद) को हटाने के लिए नहीं करना चाहते हैं:

testLogger.handlers = [ 
    h for h in testLogger.handlers if not isinstance(h, logging.StreamHandler)] 
सूची में ज के लिए
+0

क्षमा करें, मैंने पाया कि यह काम नहीं करता है। क्योंकि इंस्टालेंस का उपयोग हैंडलर के प्रकार –

+1

@fat_cheng का न्याय करने के लिए नहीं किया जा सकता है, उस उद्देश्य के लिए काम क्यों नहीं कर सकता? मुझे इस जवाब में सुझाव का उपयोग करके कोई समस्या नहीं है। – AlanSE

+0

मैं उबंटू 16.04 में पायथन 3 का उपयोग कर रहा हूं। मैं 'if (टाइप (एच) == लॉगिंग। स्ट्रीमहैंडलर)] 'का उपयोग करता हूं। –

संबंधित मुद्दे