2012-02-17 8 views
19

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

ऐसा कहने के लिए, जब यह बंद हो जाता है, मुझे लगता है कि sys.stdout बंद हो जाता है, इसलिए प्रिंटिंग, और इस वर्ग का उपयोग फिर से विफल हो जाता है। मैंने sys, और अन्य गूंगा सामान reimporting की कोशिश की, लेकिन मैं इसे काम करने के लिए नहीं मिल सकता है।

यहाँ साइट है, और कोड groups.google.com/group/comp.lang.python/browse_thread/thread/d25a9f5608e473af/

import sys 

class MyWriter: 

    def __init__(self, stdout, filename): 
     self.stdout = stdout 
     self.logfile = file(filename, 'a') 

    def write(self, text): 
     self.stdout.write(text) 
     self.logfile.write(text) 

    def close(self): 
     self.stdout.close() 
     self.logfile.close() 

writer = MyWriter(sys.stdout, 'log.txt') 
sys.stdout = writer 

print 'test' 
+0

जब बंद हो जाता है? मुझे वहां कुछ भी बंद नहीं दिख रहा है। –

+0

आपको जवाब स्वीकार करना चाहिए, वास्तव में – gt6989b

उत्तर

83

आप पाइथन मानक पुस्तकालय द्वारा बहुत अच्छी तरह से किए गए कुछ खराब पुनरुत्पादन की कोशिश कर रहे हैं; कृपया logging module देखें।

इस मॉड्यूल के साथ आप वही कर सकते हैं जो आप चाहते हैं, लेकिन एक बहुत ही सरल, मानक और एक्स्टेंसिबल तरीके से।

Let’s say you want to log to console and file with different message formats and in differing circumstances. Say you want to log messages with levels of DEBUG and higher to file, and those messages at level INFO and higher to the console. Let’s also assume that the file should contain timestamps, but the console messages should not. Here’s how you can achieve this:

import logging 

# set up logging to file - see previous section for more details 
logging.basicConfig(level=logging.DEBUG, 
        format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', 
        datefmt='%m-%d %H:%M', 
        filename='/temp/myapp.log', 
        filemode='w') 
# define a Handler which writes INFO messages or higher to the sys.stderr 
console = logging.StreamHandler() 
console.setLevel(logging.INFO) 
# set a format which is simpler for console use 
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') 
# tell the handler to use this format 
console.setFormatter(formatter) 
# add the handler to the root logger 
logging.getLogger('').addHandler(console) 

# Now, we can log to the root logger, or any other logger. First the root... 
logging.info('Jackdaws love my big sphinx of quartz.') 

# Now, define a couple of other loggers which might represent areas in your 
# application: 

logger1 = logging.getLogger('myapp.area1') 
logger2 = logging.getLogger('myapp.area2') 

logger1.debug('Quick zephyrs blow, vexing daft Jim.') 
logger1.info('How quickly daft jumping zebras vex.') 
logger2.warning('Jail zesty vixen who grabbed pay from quack.') 
logger2.error('The five boxing wizards jump quickly.') 

When you run this, on the console you will see

root  : INFO  Jackdaws love my big sphinx of quartz. 
myapp.area1 : INFO  How quickly daft jumping zebras vex. 
myapp.area2 : WARNING Jail zesty vixen who grabbed pay from quack. 
myapp.area2 : ERROR The five boxing wizards jump quickly. 

and in the file you will see something like

10-22 22:19 root   INFO  Jackdaws love my big sphinx of quartz. 
10-22 22:19 myapp.area1 DEBUG Quick zephyrs blow, vexing daft Jim. 
10-22 22:19 myapp.area1 INFO  How quickly daft jumping zebras vex. 
10-22 22:19 myapp.area2 WARNING Jail zesty vixen who grabbed pay from quack. 
10-22 22:19 myapp.area2 ERROR The five boxing wizards jump quickly. 

As you can see, the DEBUG message only shows up in the file. The other messages are sent to both destinations.

This example uses console and file handlers, but you can use any number and combination of handlers you choose.

+3

+1 स्क्रीन पर लॉगिंग के लिए सभी SO प्रश्नों में सर्वश्रेष्ठ उत्तर और फ़ाइल –

+0

मुझे यह जवाब पसंद है, लेकिन मुझे यकीन नहीं है कि मूल पोस्टर यह पूछ रहा था। ... फ़ाइल "C: \ Anaconda2 \ lib \ प्रवेश –

+0

जब ऊपर बिल्कुल कोड नकल, के बाद ' logging.info मैं निम्नलिखित त्रुटि मिलती है ('jackdaws क्वार्ट्ज की मेरा बड़ा स्फिंक्स प्यार करता हूँ।') ' \ 0__ init__.py ", लाइन 467, प्रारूप रिकॉर्ड.एएसटीएमआईएम = self.formatTime (रिकॉर्ड, self.datefmt) फ़ाइल" सी: \ Anaconda2 \ lib \ logging \ __ init__.py ", लाइन 425, प्रारूप समय एस में = time.strftime (datefmt, ct) ValueError: अवैध प्रारूप स्ट्रिंग क्या कोई मदद कर सकता है? – riccio777

1

लाइन है कि कर रहा है निकालें क्या आप स्पष्ट रूप से आप कहते हैं कि डॉन नहीं करना चाहता: बंद() की पहली पंक्ति, जो stdout बंद कर देता है।

0

That is to say, when it closes, I think sys.stdout closes, so printing at all, and using this class again fails. I tried reimporting sys, and other dumb stuff, but I can't get it to work.

आपके प्रश्न का उत्तर करने के लिए: इस प्रकार आप आगे बढ़ सकते हैं (इस उदाहरण logging cookbook से एक कॉपी/पेस्ट न करें) , आपको बंद नहीं होना चाहिए stdout। पायथन दुभाषिया स्टार्टअप पर stdout, stdin और stderror खुलता है। काम पर प्रिंट करने के लिए, दुभाषिया को स्टडआउट खोलने की आवश्यकता होती है। एक बार मॉड्यूल लोड होने के बाद reimporting sys कुछ भी नहीं करता है। आपको मॉड्यूल को फिर से लोड करना होगा। इस विशेष मामले में, मुझे यकीन नहीं है कि एक रीलोड समस्या को ठीक करेगा क्योंकि sys.stdout फ़ाइल ऑब्जेक्ट के रूप में stdout को उपयोग करने की अनुमति देता है।

इसके अतिरिक्त, मुझे लगता है कि आपके पास आपके कोड में एक बग है जो ब्रेक पर प्रिंट कर सकती है। लाइन 2 में आप sys.stdout पर MyWriter ऑब्जेक्ट असाइन कर रहे हैं। यह स्टडआउट बंद करके हो सकता है जब कचरा कलेक्टर अप्रयुक्त stdout फ़ाइल ऑब्जेक्ट को हटा देता है।

writer = MyWriter(sys.stdout, 'log.txt') 
sys.stdout = writer 
4

अजगर 3.3 के साथ आसान peasy और

ऊपर अजगर 3.3 के साथ शुरू है, तो काफी आसान के बाद से logging.basicConfig अब handlers = तर्क स्वीकार करता है बन गया है ऐसा करने।

import logging 

level = logging.INFO 
format = ' %(message)s' 
handlers = [logging.FileHandler('filename.log'), logging.StreamHandler()] 
logging.basicConfig(level = level, format = format, handlers = handlers) 

logging.info('Hey, this is working!') 

नोट तथापि, कि कुछ पायथन मॉड्यूल भी INFO स्तर पर प्रवेश संदेशों पोस्ट करने वाले हैं।

यह जहां यह create a custom logging level के काम आता है, उदाहरण के OK के लिए बुलाया है, डिफ़ॉल्ट INFO स्तर से ऊपर 5 स्तरों और डिफ़ॉल्ट WARNING स्तर से नीचे 5 स्तरों।

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