2009-11-27 15 views
14

मैं कुछ कोड के कुछ यूनिट परीक्षण लिख रहा हूं जो इनपुट में त्रुटियों की रिपोर्ट करने के लिए sys.stderr.write का उपयोग करता है। यह वही होना चाहिए, लेकिन यह इकाई परीक्षण आउटपुट clobbers। क्या पाइथन को एकल आदेशों के लिए त्रुटि संदेशों को आउटपुट करने का कोई तरीका नहीं है, à la 2> /dev/null?इकाई परीक्षणों में stderr आउटपुट को छिपाएं

उत्तर

23

मैं एक संदर्भ प्रबंधक लेखन सलाह देते हैं:

import contextlib 
import sys 

@contextlib.contextmanager 
def nostderr(): 
    savestderr = sys.stderr 
    class Devnull(object): 
     def write(self, _): pass 
     def flush(self): pass 
    sys.stderr = Devnull() 
    try: 
     yield 
    finally: 
     sys.stderr = savestderr 

अब, किसी भी कोड का टुकड़ा जिसका stderr आप एक with nostderr(): में दबा दिया चाहते हैं और आप स्थानीय है, अस्थायी, इसकी गारंटी-प्रतिवर्ती stderr दमन जो आप चाहते लपेट दें।

+1

वाह! यह अद्भुत है। Coz से पहले contextlib के बारे में पता नहीं था मैं अभी भी पायथन 2.4 का उपयोग करें। –

+0

@ शैलेश, हां, संदर्भलिब सबसे सरल संदर्भ प्रबंधकों के लेखन की सुविधा प्रदान करता है ('__enter__' और' __exit__' वाली कक्षा लिखना मुश्किल नहीं है, लेकिन इस तरह, पर्याप्त सरल मामलों के लिए, आपके पास कम बॉयलरप्लेट कोड भी है लिखो और पढ़ें ;-)। –

+0

क्यों नहीं 'sys.stderr = os.devnull' – Matt3o12

4
class DevNull(object): 
    def write(self, data): pass 

sys.stderr = DevNull() 

एक कम स्थायी समाधान करवाने के लिए, एक कुछ यह पता लगाने सकता है की तरह इस प्रकार है:

_stderr = None 
def quiet(): 
    global _stderr 
    if _stderr is None: 
     _stderr = sys.stderr 
     sys.stderr = DevNull() 

def verbose(): 
    global _stderr 
    if _stderr is not None: 
     sys.stderr = _stderr 
     _stderr = None 

समारोह के नाम शायद बेहतर हो

+0

मैं कम स्थायी समाधान की उम्मीद कर रहा था। क्या 'शांत (...)' जैसे कमांड को लपेटने का कोई तरीका नहीं है? – l0b0

+1

बैकअप को स्टोर करने की कोई आवश्यकता नहीं है। पाइथन में पहले से ही एक sys है .__ stderr__ http://docs.python.org/library/sys.html#sys.__stderr__ –

+1

बैकअप को स्टोर करने का कारण यह है कि कुछ भी पूर्ण नहीं है: कौन जानता है कि कुछ अन्य बड़ी कोड इकाई sys बदल गई है आपके द्वारा बुलाए जाने से पहले। इस तरह, आप बस अपनी पहली कार्रवाई को पूर्ववत कर रहे हैं। –

12

आप एक डमी फ़ाइल उद्देश्य यह है कि कुछ नहीं किया बना सकते हैं कर सकते हैं इसके आउटपुट के साथ, और उस पर stderr सेट करें:

class NullWriter: 
    def write(self, s): 
     pass 

sys.stderr = NullWriter() 

यदि आप केवल stde को शांत करना चाहते हैं rr एक विशिष्ट अवधि के लिए, यदि आप ऐसा तरह एक with कथन का उपयोग कर सकते हैं:

class Quieter: 
    def __enter__(self): 
     self.old_stderr = sys.stderr 
     sys.stderr = NullWriter() 

    def __exit__(self, type, value, traceback): 
     sys.stderr = self.old_stderr 

with Quieter(): 
    # Do stuff; stderr will be suppressed, and it will be restored 
    # when this block exits 

अजगर 2.6 या उच्चतर की आवश्यकता है, या आप अजगर 2.5 में उपयोग कर सकते हैं एक from __future__ import with_statement साथ।

4

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

class DevNull(object): 
    def write(self, data): 
     pass 

class MyTestCase(unittest.TestCase): 
    def setUp(self): 
     self.old_stderr = sys.stderr 
     sys.stderr = DevNull() 

    def tearDown(self): 
     sys.stderr = self.old_stderr 

, लेकिन फिर अंत में यह पुनर्स्थापित करता है:

आप sys.stderr पुन: असाइन करना चाहते हैं, तो आप unittest ढांचे आप के लिए यह प्रबंधन करने के लिए उपयोग कर सकते हैं परीक्षण का।

+0

यह भी लाभ है कि आप अपने परीक्षण में आउटपुट की जांच कर सकते हैं यदि आप चाहते थे। –

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