2012-02-16 20 views
8

मैं लॉगिंग (कॉलर का क्लास नाम, मॉड्यूल नाम इत्यादि) के लिए एक कस्टम विशेषता बनाने की कोशिश कर रहा था और मुझे एक अजीब अपवाद के साथ फंस गया कि मुझे बता रहा है कि प्रक्रिया में बनाए गए LogRecord इंस्टेंस में नहीं था आवश्यक गुण। परीक्षण का एक सा होने के बाद मैं इस के साथ समाप्त हो गया:पायथन लॉगिंग मॉड्यूल: कस्टम लॉगर्स

import logging 

class MyLogger(logging.getLoggerClass()): 
    value = None 

logging.setLoggerClass(MyLogger) 

loggers = [ 
    logging.getLogger(), 
    logging.getLogger(""), 
    logging.getLogger("Name") 
] 

for logger in loggers: 
    print(isinstance(logger, MyLogger), hasattr(logger, "value")) 

कोड पैदावार की यह मालूम होता है सही टुकड़ा:

False False 
False False 
True True 

बग या सुविधा?

उत्तर

5

स्रोत कोड हम निम्नलिखित देख सकते हैं को देखते हुए:

root = RootLogger(WARNING) 
def getLogger(name=None): 
    if name: 
     return Logger.manager.getLogger(name) 
    else: 
     return root 

यही है, एक रूट लकड़हारा जब मॉड्यूल आयात किया जाता है डिफ़ॉल्ट रूप से बनाया जाता है। इसलिए, हर बार जब आप रूट लूगर (खाली स्ट्रिंग जैसे झूठे मूल्य को पास करते हैं) की तलाश करते हैं, तो आपको logging.setLoggerClass पर किसी भी कॉल के बावजूद logging.RootLogger ऑब्जेक्ट प्राप्त करने जा रहे हैं।

लकड़हारा वर्ग के बारे में इस्तेमाल किया जा रहा है कि हम देख सकते हैं:

_loggerClass = None 
def setLoggerClass(klass): 
    ... 
    _loggerClass = klass 

इसका मतलब यह है कि एक वैश्विक चर लकड़हारा वर्ग भविष्य में प्रयोग की जाने वाली है।

इस के अलावा, logging.Manager (logging.getLogger द्वारा प्रयुक्त) को देखते हुए, हम यह देख सकते हैं:

def getLogger(self, name): 
    ... 
      rv = (self.loggerClass or _loggerClass)(name) 

यही है, अगर self.loggerClass सेट नहीं है (जो जब तक आप स्पष्ट है नहीं होगा इसे सेट करें), वैश्विक चर से कक्षा का उपयोग किया जाता है।

इसलिए, यह एक सुविधा है। रूट लॉगर हमेशा logging.RootLogger ऑब्जेक्ट होता है और उस समय कॉन्फ़िगरेशन के आधार पर अन्य लॉगर ऑब्जेक्ट्स बनाए जाते हैं।

2

logging.getLogger() और logging.getLogger("") एक MyLogger नहीं लौटते हैं, क्योंकि वे प्रवेश पदानुक्रम की जड़ लकड़हारा लौटने के लिए, logging documentation में वर्णित हैं:

logging.getLogger ([नाम])

वापसी एक निर्दिष्ट नाम के साथ लॉगर या, यदि कोई नाम निर्दिष्ट नहीं है, तो एक लॉगर लौटाएं जो पदानुक्रम का रूट लॉगर है।

इस प्रकार, आप के रूप में लकड़हारा की स्थापना:

>>> logging.getLogger() 
<logging.RootLogger object at 0x7d9450> 
>>> logging.getLogger("foo") 
<test3.MyLogger object at 0x76d9f0> 

मुझे नहीं लगता कि इस KeyError से संबंधित है के साथ अपनी पोस्ट शुरू कर दिया। आपको वह कोड पोस्ट करना चाहिए जिससे उस अपवाद को फेंक दिया जाए (test.py)।

+0

आपकी टिप्पणी के लिए धन्यवाद, मैंने प्रश्न संपादित किया है। लेकिन मुझे लगता है कि यह व्यवहार ऐसा नहीं है जो कोई होने की उम्मीद करेगा। – Pastafarianist

+0

ऐसा क्यों नहीं है जो आप होने की उम्मीद करेंगे? यह * सटीक * दस्तावेज कहता है जब कोई नाम निर्दिष्ट नहीं होता है। –

+4

भले ही दस्तावेज कहता है, यह काउंटर-अंतर्ज्ञानी है। लॉगर्स के लिए कक्षा निर्धारित करना, मैं उम्मीद करता हूं कि _all_ लॉगर्स उस वर्ग के पास हों, जिसमें रूट एक शामिल है और पहले से ही तत्काल को छोड़कर। – Pastafarianist

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