Python interpreter uses the following three file objects on the sys library for standard input, output, and errors (exceptions):
- sys.stdin is used for input from the input() function call,
- sys.stdout – used for output of print() function and the prompt in the input(),
- sys.stderr – Python interpreter’s own prompts (like help() function output), errors and exceptions go to this file object.
Both sys.stdout and sys.stderr print to the output console; the key difference is that the former prints the standard output, but the latter prints errors and exceptions.
This article discusses how to prevent Python from writing output into the console. We will do that in two ways: silence sys.stdout and sys.stderr or redirect the output into a file. Let’s work on examples.
Example 1: Suppress print() Function Output
The print() function contains file argument that determines the file object to send our output. If it is not given, it uses sys.stdout. The two print statements in the code example below are equivalent; they print the given string on the console.
1 2 3 4 |
import sys print("This will go to STDOUT.", file=sys.stdout) print("This will go to STDOUT.") |
We can send the output into a file with the following example. The print statement won’t write anything into the console.
1 2 3 4 5 6 7 |
# Open a file in write mode. f = open("code1.log", "w") # Send print output into "code1.log" print("This will go to a file.", file = f) # For Python 3. # print >> f, "This will go to a file" # For Python 2. # Close the file f.close() |
If we don’t want to write the output to the console or a physical file, we can write the output to the null device (/dev/null in UNIX and nul in Windows). Anything written to the null device will be discarded and forgotten. In Python, the null device is available on os.devnull.
We can suppress the console output by writing the output to the null device, as shown in the code below.
1 2 3 4 5 |
# Open the null_device in write mode. null_device = open(os.devnull, "w") # Write output to the file, which is nowhere, really. print("This will go to the null device. Into nothingness really.", file = null_device) null_device.close() |
The alternative to os.devnull is io.StringIO() – in-memory file-like object to hold the output without displaying it on the console.
Unlike os.devnull, which is not readable, io.StringIO() will hold our data on the memory buffer, and we can access it within the current interpreter session.
1 2 3 |
import io print("This will go to STDOUT.", file=io.StringIO()) |
Example 2: Suppressing Console Output for a Large Block of Code (for Python 3.4+)
In Example 1, we saw how to suppress the console output within the print statement. The weakness of that example is that we need to redirect output for each print statement.
Let’s fix that. We want to suppress the console output from a block of code instead of doing it line by line. The contextlib package comes in handy here.
Remember: The following code example works in Python 3.4+. If you are running an older version, check Example 3.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Available for Python 3.4 and later. from contextlib import redirect_stdout import io # Redirecting STDOUT with redirect_stdout(io.StringIO()) as f: # All code lines generating console output within this context manager # will have those outputs suppressed. print(help(abs)) m1 = 5 * 7 # The value of m1 here will be printed on the console. print(m1) print("You won't see this on STDOUT because STDOUT is redirected.") # The value, m1, will be printed on the console print(m1) print("But you can see this because it is outside redirecting context manager.") |
Output (on the console):
35 But you can see this because it is outside redirecting context manager.
The output within the redirect_stdout context manager is suppressed in the example above. Alternatively, we can send the output to a file.
1 2 3 4 5 6 7 8 9 10 11 |
<a id="post-2760-_f5bbduiq8f9"></a>from contextlib import redirect_stdout # Sending the output to a file with open("code.log", "w") as outfile: with redirect_stdout(outfile): # All contents returned by print statements in this block # will be written to "code.log" file instead of the console. print(help(abs)) m1 = 5 * 7 print(m1) print("You won't see this on STDOUT because STDOUT is redirected.") |
Example 3: Suppressing Console Output on Python 3.3 and Older
The contextlib.redirect_output used in Example 2 was introduced in Python 3.4. You can use this code if you are running Python 3.3 and older.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
from contextlib import contextmanager import os, sys # Using contextmanager decorator to enable us to call the suppress_output() # function as a context manager using the "with" statement. @contextmanager def suppress_output(file=os.devnull): # file is set to os.devnull by default. # os.devnull is a null device in which whatever we write to it is discarded. # You also import io and use io.StringIO() intead of os.devnull with open(file, "w") as f: # Get the original file object for sys.stdout original_stdout = sys.stdout # Change the sys.stdout to be the null device. sys.stdout = f try: yield None finally: # This part of the try-block will be executed # to set the sys.stdout to the original stdout file object. # Undoing the modification we have done to the stdout file object. sys.stdout = original_stdout # Calling suppress_output() function using "with" context manager. with suppress_output(): # Anything output under the function call will be suppressed. print(5 * 4) print("You wont see this on the console.") print(5 * 4) print("But you can see this on the console.") with suppress_output(file="code4.log"): # Send the outpout to a file. print(6 * 6) print("This string will be sent to a file instead of being sent to the console.") print(6 * 7) print("This will be printed on the console.") |
Output (on the console):
20 But you can see this on the console. 42 This will be printed on the console.
Example 4: Suppressing Console Output from subprocess
You will get some output on the console if you run terminal commands from within Python using a subprocess. This output may emanate from sys.stdout or sys.stderr. This means we need to redirect the output from both of those streams. Here is how to send the output to a file.
1 2 3 4 5 6 7 8 9 |
import subprocess # Send subprocess output to a file. f = open("code2.log", "w") # Using ffmpeg to extract frames from a video. One frame in each second. command = "ffmpeg -i video1.mp4 -f image2 -vf fps=fps=1 ./images/output%d.png" # Run the command and send output to a file. subprocess.call(command.split(" "), stdout=f, stderr=f) f.close() |
You can also suppress it by sending the output to subprocess.DEVNULL (it calls os.devnull under the hoods).
1 2 3 4 5 6 7 8 |
<a id="post-2760-_j7tcr148unk"></a>import subprocess command = "ffmpeg -i video1.mp4 -f image2 -vf fps=fps=1 ./images/output%d.png" # Redirect the output into null device. You won't see anything on the console # and the redirected output can't be retrived. subprocess.call( command.split(" "), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL ) |
Conclusion
This article discussed how to suppress console output in Python by redirecting contents of the output dreams (sys.stdout and sys.stderr). In all four examples presented, the gist is to redirect the output to a file or os.devnull (a null device that automatically discards all the contents written to it).