Почему devnull не работает при сокрытии вывода консоли, если он определен в этом диспетчере контекста?

У меня есть диспетчер контекста, определенный для «заглушения» вывода некоторого кода Python путем временного переопределения stdout и stderr.

Когда devnull определен в основной функции кода, вывод кода успешно подавляется, однако, когда devnull определен в диспетчере контекста, вывод кода не отключается.

Почему это? Как диспетчер контекста может заглушить вывод, одновременно определяя devnull?

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()

person d3pd    schedule 30.04.2016    source источник


Ответы (1)


В вашем методе __ init __, когда аргументы stderr и stdout равны None, вы определяете devnull, но не присваиваете это значение stderr и stdout. Следовательно, stderr и stdout являются ложными, поэтому выходные потоки остаются как sys.stderr и sys.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 
person snakecharmerb    schedule 30.04.2016
comment
О, дорогой, ты абсолютно прав. Сейчас работает нормально. Спасибо, что заметили это. - person d3pd; 30.04.2016