2012-06-11 22 views
65

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

समारोह नाम प्राप्त करने के लिए
  1. , मैं function_name.__name__ उपयोग कर सकते हैं, लेकिन मैं (function_name उपयोग करने के लिए इतना है कि मैं तेजी से कॉपी और एक सामान्य Log.info("Message") में पेस्ट कर सकता है नहीं करना चाहती:

    यहाँ मैं क्या पता है सभी कार्यों का शरीर)। मुझे पता है कि यह __func__ मैक्रो का उपयोग कर सी में किया जा सकता है लेकिन मुझे अजगर के बारे में निश्चित नहीं है।

  2. फ़ाइल नाम और लाइन नंबर प्राप्त करने के लिए, मैंने देखा है कि (और मुझे लगता है कि विश्वास करते हैं) अपने आवेदन अजगर locals() समारोह का उपयोग कर रहा है, लेकिन एक वाक्य रचना है कि मैं जैसे की पूरी तरह से अवगत नहीं हूँ में: options = "LOG.debug('%(flag)s : %(flag_get)s' % locals()) और मैं इसे उपयोग करने की कोशिश की तरह LOG.info("My message %s" % locals()) जो {'self': <__main__.Class_name object at 0x22f8cd0>} जैसे कुछ उत्पन्न करता है। इस पर कोई इनपुट कृपया?

  3. मुझे पता है कि लॉगिंग का उपयोग कैसे करें और फ़ाइल में लॉग इन करने के लिए हैंडलर जोड़ें, लेकिन मुझे यकीन नहीं है कि परियोजना में फ़ंक्शन कॉल के सही क्रम में सभी लॉग संदेशों को रिकॉर्ड करने के लिए एक फ़ाइल का उपयोग किया जा सकता है या नहीं।

मैं किसी भी मदद की सराहना करता हूं।

धन्यवाद!

+0

आप 'आयात पीडीबी का उपयोग करके अजगर डीबगर में जा सकते हैं; pdb.set_trace() ', और उसके बाद कोड के माध्यम से अंतःक्रियात्मक कदम। इससे आपको प्रोग्राम प्रवाह का पता लगाने में मदद मिल सकती है। –

+0

महान विचार! धन्यवाद मैट। प्रश्न में उल्लिखित लॉग प्राप्त करना अभी भी सहायक होगा ताकि मुझे हर बार डीबग करने की आवश्यकता न हो। साथ ही, क्या आप पाइथन के लिए एक आईडीई के बारे में जानते हैं जो जावा के लिए एक्लिप्स के रूप में अच्छा है (ctrl + क्लिक आपको फ़ंक्शन परिभाषा में ले जाता है) कि मैं डिबगिंग को आसान बनाने के लिए उपयोग कर सकता हूं? – user1126425

उत्तर

17

आपके यहां कुछ मामूली संबंधित प्रश्न हैं।

मैं सबसे आसान से शुरू करूंगा: (3)। logging का उपयोग करके आप सभी कॉल को एक ही लॉग फ़ाइल या अन्य आउटपुट लक्ष्य में जोड़ सकते हैं: वे प्रक्रिया में होने वाले क्रम में होंगे।

अगला: (2)। locals() वर्तमान दायरे का एक नियम प्रदान करता है। इस प्रकार, किसी विधि में जिसमें कोई अन्य तर्क नहीं है, आपके पास self दायरे में है, जिसमें वर्तमान उदाहरण का संदर्भ शामिल है। जिस चाल का उपयोग किया जा रहा है, वह आपको % ऑपरेटर के आरएचएस के रूप में एक dict का उपयोग करके स्ट्रिंग स्वरूपण है। "%(foo)s" % bar को bar["foo"] का मान भी बदला जाएगा।

अंत में, आप कुछ आत्मनिरीक्षण चाल, कि अधिक जानकारी के लॉग इन कर सकते pdb द्वारा इस्तेमाल किया उन लोगों के समान उपयोग कर सकते हैं:

def autolog(message): 
    "Automatically log the current function details." 
    import inspect, logging 
    # Get the previous frame in the stack, otherwise it would 
    # be this function!!! 
    func = inspect.currentframe().f_back.f_code 
    # Dump the message + the name of this function to the log. 
    logging.debug("%s: %s in %s:%i" % (
     message, 
     func.co_name, 
     func.co_filename, 
     func.co_firstlineno 
    )) 

यह संदेश में पारित कर दिया, प्लस (मूल) समारोह का नाम, फ़ाइल नाम प्रवेश करेंगे जिसमें परिभाषा प्रकट होती है, और उस फ़ाइल में रेखा। अधिक जानकारी के लिए inspect - Inspect live objects पर एक नज़र डालें।

जैसा कि मैंने पहले अपनी टिप्पणी में उल्लेख किया था, आप pdb इंटरैक्टिव डिबगिंग प्रॉम्प्ट में किसी भी समय import pdb; pdb.set_trace() लाइन डालने और अपने प्रोग्राम को फिर से चलाकर भी छोड़ सकते हैं। यह आपको कोड के माध्यम से कदम उठाने में सक्षम बनाता है, जैसा कि आप चुनते हैं डेटा का निरीक्षण करते हैं।

logger.debug('your message') 

उदाहरण आउटपुट एक स्क्रिप्ट मैं सही पर काम कर रहा हूँ से:

+0

धन्यवाद मैट! मैं इस autolog समारोह की कोशिश करेंगे। मुझे% ऑपरेटर के आरएचएस के रूप में उपयोग करने वाले नियम के बारे में थोड़ा उलझन है: क्या '% (foo) s:% (bar) s'' 'bar [" foo "] के मान को भी प्रिंट करेगा? या यह आपके उदाहरण से कुछ अलग है? – user1126425

+0

मूल रूप से, '% () एस' के रूप में सबकुछ '' द्वारा दिए गए ऑब्जेक्ट के संदर्भ में प्रतिस्थापित किया गया है। Http://docs.python.org/library/stdtypes.html#string-formatting –

+0

@synthesizerpatel के उत्तर पर अधिक उदाहरण/विवरण हैं और अधिक उपयोगी है। – Jan

276

इस के लिए सही जवाब, कहीं भी आप चाहते हैं तो पहले से ही प्रदान की funcName चर

import logging 
logger = logging.getLogger('root') 
FORMAT = "[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s" 
logging.basicConfig(format=FORMAT) 
logger.setLevel(logging.DEBUG) 

उपयोग करने के लिए बस को जोड़ने है अब:

[invRegex.py:150 -   handleRange() ] ['[A-Z]'] 
[invRegex.py:155 -  handleRepetition() ] [[<__main__.CharacterRangeEmitter object at 0x10ba03050>, '{', '1', '}']] 
[invRegex.py:197 -   handleMacro() ] ['\\d'] 
[invRegex.py:155 -  handleRepetition() ] [[<__main__.CharacterRangeEmitter object at 0x10ba03950>, '{', '1', '}']] 
[invRegex.py:210 -  handleSequence() ] [[<__main__.GroupEmitter object at 0x10b9fedd0>, <__main__.GroupEmitter object at 0x10ba03ad0>]] 
+20

यह जवाब होना चाहिए था! – user3885927

+1

ग्रेट .. जोड़ने के लिए एक चीज, क्या हम लॉगफाइल को गतिशील रूप से कोडफाइल के समान ही नाम दे सकते हैं? उदाहरण: मैंने लॉगिंग.बासिक कॉनफिग (फ़ाइल नाम = "% (फ़ाइल नाम)", प्रारूप = FORMAT) गतिशील रूप से फ़ाइल नाम लेने के लिए प्रयास किया, लेकिन यह स्थिर मान लिया। कोई उपाय? – Outlier

+2

@ वैकल्पिक नहीं, प्राप्त करने के लिए अनुशंसित तरीका 'getLogger (__ नाम __) ' – farthVader

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