2016-04-30 2 views
0

私は、stdoutとstderrを一時的に再定義することによって、いくつかのPythonコードの出力を「サイレンシング」する目的で定義されたコンテキストマネージャを持っています。コンソール・アウトプットがこのコンテキスト・マネージャー内で定義されているときに、コンソール出力を隠すときにdevnullが機能しないのはなぜですか?

devnullがコードのmain関数で定義されている場合、コードの出力は正常に終了しますが、devnullがコンテキストマネージャで定義されている場合、コードの出力は消されません。

これはなぜですか?コンテキストマネージャは、devnullを定義している間に、どのように出力を抑止することができますか? stderrstdout引数はあなたがdevnullを定義していますがstderrstdoutにこの値を割り当てないNoneあるご__ init __方法では、

import os 
import sys 

def main(): 

    print("hello") 

    devnull = open(os.devnull, "w") 
    with silence(
     stdout = devnull, 
     stderr = devnull 
     ): 
     print("there") 

    print("world") 

class silence(object): 

    def __init__(
     self, 
     stdout = None, 
     stderr = None 
     ): 
     if stdout == None and stderr == None: 
      devnull = open(os.devnull, "w") 
     self._stdout = stdout or sys.stdout 
     self._stderr = stderr or sys.stderr 

    def __enter__(
     self 
     ): 
     self.old_stdout = sys.stdout 
     self.old_stderr = sys.stderr 
     self.old_stdout.flush() 
     self.old_stderr.flush() 
     sys.stdout = self._stdout 
     sys.stderr = self._stderr 

    def __exit__(
     self, 
     exc_type, 
     exc_value, 
     traceback 
     ): 
     self._stdout.flush() 
     self._stderr.flush() 
     sys.stdout = self.old_stdout 
     sys.stderr = self.old_stderr 

if __name__ == "__main__": 
    main() 

答えて

1

。その結果、stderrstdoutは偽であるため、出力ストリームはsys.stderrsys.stdoutのままです。

class silence(object): 

    def __init__(
     self, 
     stdout = None, 
     stderr = None 
     ): 
     if stdout == None and stderr == None: 
      devnull = open(os.devnull, "w") 
      # Assign devnull to stdout and stderr 
      stdout = devnull 
      stderr = devnull 
     self._stdout = stdout or sys.stdout 
     self._stderr = stderr or sys.stderr 
+0

おはよう、あなたは絶対に正しいです。今はうまくいっています。それを見つけていただきありがとうございます。 – d3pd

関連する問題