केवल डीबग करने के लिए प्रिंट स्टेटमेंट का उपयोग करना


109

मैं देर से पायथन में कोडिंग कर रहा हूं। और मैं उन डेटा के साथ काम कर रहा हूं, जिनके साथ मैंने पहले काम नहीं किया है, पहले कभी नहीं देखी गई फ़ार्मुलों का उपयोग करते हुए और बड़ी फ़ाइलों के साथ काम करते हुए। यह सब मुझे सत्यापित करने के लिए बहुत सारे प्रिंट स्टेटमेंट बनाता है कि क्या यह सब सही हो रहा है और विफलता के बिंदुओं की पहचान करें। लेकिन, आम तौर पर, इतनी जानकारी का उत्पादन एक अच्छा अभ्यास नहीं है। मैं केवल प्रिंट स्टेटमेंट का उपयोग कैसे करूं, जब मैं डिबग करना चाहता हूं और जब मैं उन्हें प्रिंट नहीं करना चाहता, तो उन्हें छोड़ देना चाहिए?

जवाबों:


161

loggingमॉड्यूल सब कुछ आप चाहते हैं सकता है। यह पहली बार में अत्यधिक लग सकता है, लेकिन केवल उन हिस्सों का उपयोग करें जिनकी आपको आवश्यकता है। मैं का उपयोग कर की सलाह देते हैं logging.basicConfigकरने के लिए लॉगिंग स्तर टॉगल करने के लिए stderrऔर सरल लॉग तरीकों , debug, info, warning, errorऔर critical।

import logging, sys
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
logging.debug('A debug message!')
logging.info('We processed %d records', len(processed_records))

5
इसके अलावा, अगर आपको मेरे जैसे मॉड्यूल को स्थापित करने में परेशानी होती है; लॉगिंग मानक पुस्तकालय का एक हिस्सा है - एक आभासी वातावरण का उपयोग करते समय भी पाइप स्थापित करने की कोई आवश्यकता नहीं है
— अमृत

लॉगिंग का स्तर कैसे निर्धारित करता है जैसे कि यह केवल त्रुटियों को प्रिंट करता है और संदेशों को डिबग नहीं करता है?
— एडुआर्डो पिगनैटेली

@EduardoPignatelli सेट level, basicConfigकॉल में, को logging.ERROR।
— मैट जॉइनर

मुझे डर है कि यह ज्यूपिटर लैब 1.2.6 पर काम नहीं करता है। आप लॉगिंग स्तर को एक बार सेट कर सकते हैं, और पुन: सेटिंग का उपयोग logging.basicConfig(stream=sys.stderr, level=logging.ERROR)कर रहा है कोई प्रभाव नहीं होगा। कर्नेल को पुनरारंभ करना और नए स्तर के कार्यों को सेट करना, लेकिन यह मेरे लिए एक समाधान है।
— एडुआर्डो पिग्नाटेली

@EduardoPignatelli आपको इसके लिए एक और सवाल पूछना चाहिए। लेकिन संभावना है कि आपको सीधे रूट लकड़हारे के स्तर को बदलने की आवश्यकता होगी, जुपिटर शायद आपके सामने बेसिकफोन को बुला रहा है।
— मैट जॉइनर

28

ऐसा करने का एक सरल तरीका लॉगिंग फ़ंक्शन को कॉल करना है:

DEBUG = True

def log(s):
    if DEBUG:
        print s

log("hello world")

तब आप DEBUGअपना कोड बदल सकते हैं और लॉगिंग के साथ या उसके बिना अपना कोड चला सकते हैं।

मानक loggingमॉड्यूल में इसके लिए अधिक विस्तृत तंत्र है।


5
अपने स्वयं के रोल की तुलना में आपूर्ति किए गए लॉगिंग मॉड्यूल का उपयोग करने के लिए लंबे समय में संभवतः बेहतर है (भले ही यह अधिक जटिल दिखता है)।
— मियुका

11
सच है, लेकिन यह समझने योग्य है कि कोई कैसे अपना रोल कर सकता है ।
— ग्रेग हेविगेल

1
वास्तव में। ऊपर एक अच्छा विचार है कि कैसे loggingकाम करता है (बहुत सरल स्तर पर)।
— मागुका जूल

यह वह है जिसका उपयोग मैं अपने अम्ब लाम्बास के लिए करता हूं।
— crsuarezf

21

का प्रयोग करें लॉगिंग अंतर्निर्मित संग्रहालय में के बजाय मॉड्यूल मुद्रण।

आप एक Loggerऑब्जेक्ट बनाते हैं (कहते हैं logger), और उसके बाद, जब भी आप डिबग प्रिंट डालते हैं, तो आप बस डालते हैं:

logger.debug("Some string")

आप logger.setLevelआउटपुट स्तर सेट करने के लिए प्रोग्राम की शुरुआत में उपयोग कर सकते हैं । यदि आप इसे DEBUG में सेट करते हैं, तो यह सभी डिबग प्रिंट करेगा। इसे INFO या उच्चतर पर सेट करें और तुरंत सभी डीबग गायब हो जाएंगे।

आप इसका उपयोग विभिन्न स्तरों (INFO, WARNING और ERROR) में और अधिक गंभीर चीजों को लॉग करने के लिए भी कर सकते हैं।


12

सबसे पहले, मैं अजगर के लॉगिंग ढांचे के नामांकन को दूसरा स्थान दूंगा । हालाँकि आप इसका उपयोग कैसे करते हैं, इसके बारे में थोड़ा सावधान रहें। विशेष रूप से: लॉगिंग ढांचे को अपने चर का विस्तार करने दें, इसे स्वयं न करें। उदाहरण के लिए, इसके बजाय:

logging.debug("datastructure: %r" % complex_dict_structure)

सुनिश्चित करें कि आप करते हैं:

logging.debug("datastructure: %r", complex_dict_structure)

क्योंकि जब वे समान दिखते हैं, तो पहला संस्करण repr () लागत को अक्षम करता है, भले ही वह अक्षम हो । दूसरा संस्करण इससे बचें। इसी तरह, यदि आप अपना रोल करते हैं, तो मैं कुछ सुझाव दूंगा:

def debug_stdout(sfunc):
    print(sfunc())

debug = debug_stdout

के माध्यम से बुलाया:

debug(lambda: "datastructure: %r" % complex_dict_structure)

यदि आप इसे करके अक्षम कर देते हैं, तो फिर से ओवरहेड से बचें:

def debug_noop(*args, **kwargs):
    pass

debug = debug_noop

उन स्ट्रिंग्स की गणना करने का ओवरहेड शायद तब तक मायने नहीं रखता जब तक कि वे 1) या तो गणना करने के लिए महंगे या 2) डिबग स्टेटमेंट के बीच में हो, कहते हैं, एन ^ 3 लूप या कुछ और। ऐसा नहीं कि मुझे उसके बारे में कुछ पता होगा।


इस महत्वपूर्ण विषय पर अधिक जानकारी के लिए लॉगऑनिंग
— मार्टिन CR

7

मैं दूसरों के बारे में नहीं जानता, लेकिन मुझे एक "वैश्विक स्थिरांक" ( DEBUG) और फिर एक वैश्विक कार्य ( debug(msg)) को परिभाषित करने के लिए उपयोग किया जाता था जो msgकेवल तभी प्रिंट होता था DEBUG == True।

फिर मैं अपने डिबग स्टेटमेंट्स जैसे लिखता हूं:

debug('My value: %d' % value)

... फिर मैंने यूनिट परीक्षण किया और फिर कभी ऐसा नहीं किया! :)


यूनिट परीक्षण हा। ठीक है, फिर एक और बात उठाई जाती है :(
— पागलबुतलीव

1
मैं इकाई परीक्षण को हतोत्साहित नहीं करना चाहता - यह आवश्यक है। लेकिन मुझे नहीं लगता कि यह डिबगिंग तकनीक के रूप में भी लॉगिंग का विकल्प है। मैं अभी भी चीजों को जल्दी से परखने के लिए बहुत सारी छपाई करता हूं।
— मागुका जूल

@ क्रेजीबाउटलीव - ठीक से किया गया यूनिट परीक्षण बहुत अच्छा है। एक डरावना, संक्षिप्त, आसान करने के लिए प्रस्तुति के लिए अजगर में गोताखोरी के इस अध्याय के लिए एक नज़र है
— मैक

@ मिगुका - मैं त्वरित मुद्रण भी करता हूं, लेकिन यह सिर्फ एक-दो जोड़े print()हैं और परीक्षा पास करने के लिए अपने कोड को आवश्यक स्तर तक लाते हैं। मैं कभी भी print()सभी जगह भारी मात्रा में नहीं रहता । लॉगिंग भी मस्त है! :)
— मैक

2
@ एमएसी ऐसा लगता है कि आपके लिंक को अब एक स्पष्ट 'www' की आवश्यकता है - यह अब यहां होस्ट किया गया है ।
— पुलि
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.