2009-11-27 17 views

cevap

23

ben bir bağlam yöneticisi yazma öneririz: Şimdi

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 

, kimin Stderr bir with nostderr(): içinde bastırılmış istediğiniz ve istediğiniz geçici, garantili-geri dönüşlü şekilde hataları bastırma lokalize herhangi kod parçacığını sarın.

+1

Vay! Bu harika. Coz'den önce contextlib'den haberdar değildim hala Python 2.4 kullanıyorum. –

+0

@shailesh, evet, contextlib __enter__' 'sahip bir sınıf yazma en basit bağlam yöneticilerinin yazma (kolaylaştırır ve' __exit__' elbette zor değil, ama bu şekilde, yeterince basit durumlar için şunları yapmanız daha az Demirbaş kodu var yaz ve oku;-). –

+0

Neden 'sys.stderr = os.devnull' – Matt3o12

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

sys.stderr = DevNull() 

daha az kalıcı bir çözüm olması için, bir şey anlamaya olabilir:

_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 

Fonksiyon isimleri muhtemelen

+0

Daha az kalıcı bir çözüm olmasını umuyordum. Sessiz (...) gibi bir komutu sarmanın bir yolu yok mu? – l0b0

+1

Yedeği saklamanıza gerek yok. Bazı diğer büyük kod varlık sys değişirse kim bilir: Python zaten hiçbir şeyin mutlak böyledir yedeği depolamak için bir sys .__ stderr__ http://docs.python.org/library/sys.html#sys.__stderr__ –

+1

nedeni var .stderr çağırılmadan önce mi? Bu şekilde, sadece ilk eyleminizi geri alıyorsunuz. –

12

Sen hiçbir şey yapmadı bir kukla dosya nesnesi oluşturabilir iyi olabilir onun çıkışı ile ve set stderr buna:

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

sys.stderr = NullWriter() 

sadece STDE sessiz istiyorsanız rr belirli bir süre için, bunu böyle bir with deyimi kullanabilirsiniz:

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 

Python 2.6 veya üstü gerektirir, yoksa bir from __future__ import with_statement ile Python 2.5 bunu kullanabilir.

4

Başka bir olasılık da (sys.stderr'a atanmanın yanı sıra) kodunuzu sağlanan bir dosyaya hatalar yapacak şekilde yapılandırmaktır, ancak bu dosyayı varsayılan olarak sys.stderr olarak yapmaktır. Daha sonra test sırasında bir DevNull yazarı sağlayabilirsiniz.

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 

Bu şekilde, her bir test dev null en stderr'yi, ama sonra sonunda onu geri yükler: Eğer sys.stderr yeniden atamak istediğiniz takdirde

, sizin için onu yönetmek için unittest çerçevesini kullanabilirsiniz testin

+0

Bu, eğer isterseniz, testinizdeki çıkışı kontrol edebilmeniz avantajına da sahiptir. –

İlgili konular