3

I found this block of code elsewhere on stackoverflow. I've been using it quite a bit, but now I can't seem to get any print function to work, no matter how many times I execute enablePrint()... any ideas?

# Disable
def blockPrint():
    sys.stdout = open(os.devnull, 'w')

# Restore
def enablePrint():
    sys.stdout = sys.__stdout__

and Print('test') results in no output. I'm doing this all in Juptyer.

Nikolay Fominyh
  • 8,946
  • 8
  • 66
  • 102
keynesiancross
  • 3,441
  • 15
  • 47
  • 87

2 Answers2

2

In python 3 in order to work with WITH statement (context manager) you have to implement just two methods:

import os, sys

class HiddenPrints:
    def __enter__(self):
        self._original_stdout = sys.stdout
        sys.stdout = open(os.devnull, 'w')

    def __exit__(self, exc_type, exc_val, exc_tb):
        sys.stdout = self._original_stdout

Then you can use it like this:

with HiddenPrints():
    print("This will not be printed")

print("This will be printed as before")
Alexander C
  • 3,597
  • 1
  • 23
  • 39
1

You need to store the old stdin so that you can restore it:

import sys
import os

# Disable
def blockPrint():
    sys.__stdout__ = sys.stdout
    sys.stdout = open(os.devnull, 'w')

# Restore
def enablePrint():
    sys.stdout = sys.__stdout__

blockPrint()
print("test")
enablePrint()
print("test")

will print test once. Furthermore I'd recommend the use of a contextmanager:

from contextlib import contextmanager

@contextmanager
def blockPrint():
    import sys
    old_stdout = sys.stdout
    sys.stdout = None
    try:
        yield
    finally:
        sys.stdout = old_stdout

with blockPrint():
    print("test")

print("test")

which will again print test just once.

Edit: For those wondering why this can benecessary: Under some circumstances sys.__stdout__ can be None (see https://docs.python.org/3/library/sys.html) - For me this is for example the case in a Python 3.5 shell within IDLE on Windows.

Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import sys
>>> repr(sys.__stdout__)
'None'
>>> repr(sys.stdout)
'<idlelib.PyShell.PseudoOutputFile object at 0x03ACF8B0>'
  • Thanks for this. I'm still a little unclear as to why you use the context manager? (I'm using 2.7 for what its worth) – keynesiancross Feb 26 '17 at 15:40
  • If you only want to temporarily use a `resource` a context manager can make sure that that resource is *freed* afterwards. I feel the `with`-statement makes the intention more clear (and also what part of the code should be affected). But obviously there is no need to use it. – Jonathan von Schroeder Feb 26 '17 at 16:17