简体   繁体   中英

To prevent a function from printing in the batch console in Python

Well, the headline seems to me sufficient. I use some function that at some points print something in the console. As I can't modify them, I would like to know if there is a solution to not printing while using these functions.

Thanks a lot !

Nico

Yes, you can redirect sys.stdout :

import sys
import os

old_stdout = sys.stdout # backup current stdout
sys.stdout = open(os.devnull, "w")

my_nasty_function()

sys.stdout = old_stdout # reset old stdout

Just replace my_nasty_function with your actual function.

EDIT: Now should work on windows aswell.

EDIT: Use backup variable to reset stdout is better when someone wraps your function again

Constantinius' answer answer is ok, however there is no need to actually open null device. And BTW, if you want portable null device, there is os.devnull .

Actually, all you need is a class which will ignore whatever you write to it. So more portable version would be:

class NullIO(StringIO):
    def write(self, txt):
       pass

sys.stdout = NullIO()

my_nasty_function()

sys.stdout = sys.__stdout__

.

Another option would be to wrap your function in a decorator.

from contextlib import redirect_stdout
from io import StringIO 

class NullIO(StringIO):
    def write(self, txt):
        pass


def silent(fn):
    """Decorator to silence functions."""
    def silent_fn(*args, **kwargs):
        with redirect_stdout(NullIO()):
            return fn(*args, **kwargs)
    return silent_fn


def nasty():
    """Useful function with nasty prints."""
    print('a lot of annoying output')
    return 42


# Wrap in decorator to prevent printing.
silent_nasty = silent(nasty)
# Same output, but prints only once.
print(nasty(), silent_nasty())

You could use a modified version of this answer to create a "null" output context to wrap the call the function in.

That can be done by just passing os.devnull as the new_stdout argument to the stdout_redirected() context manager function when it's used.

The currently accepted answer by Constantinius works great in most circumstances, but not in Jupyter notebooks. Here's how to get it to work (with a reusable function)...

TLDR~Instead of using sys.__stout__ , backup sys.stdout and restore it later on.

In a Jupyter notebook, running sys.stdout == sys.__stdout__ returns false. This is because each cell has a separate output stream (instead of the one terminal instance, which is sys.__stdout__ ). So for everyone working with Jupyter notebooks, make sure to back up the old sys.stdout path and restore it afterwards. Here's a function for it:

import sys, os
def deafen(function, *args):
    real_stdout = sys.stdout
    sys.stdout = open(os.devnull, "w")
    output = function(*args)
    sys.stdout = real_stdout
    return output

Pass to deafen a function along with its arguments/parameters ( args ). It backs up the old sys.stdout , switches to os.devnull and back again itself.

For a complete example we can create a second function ( test_function ):

def test_function(first_argument, second_argument, *args):
    print(first_argument)
    print(second_argument)
    print(args)

Now if we try using the test_function like normal (aka without deafen ) we will get a bunch of output printed onto the screen:

print("Printing should work fine here")
test_function(32, 12, 1, 32, 1)

However, when using deafen , we'll get no new output:

print("That'll be the last thing you see...")
deafen(test_function, 32, 12, 1, 32, 1)

On a side note, the deafen function still returns a functions output. You can also use deafen with sys.__stdout__ by replacing sys.stdout = real_stdout with sys.stdout = sys.__stdout__ (and may as well remove real_stdout = sys.stdout whilst you're at it).

Hope that helps anyone who is looking for a slightly more robust or flexible solution (likely for Jupyter notebooks, or use with multiple functions)!

Constantinius' solution will work on *nix, but this should work on any platform:

import sys
import tempfile

sys.stdout = tempfile.TemporaryFile()

# Do crazy stuff here

sys.stdout.close()
#now the temp file is gone
sys.stdout = sys.__stdout__

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM