在Python中将stdout重定向到“无”

164 投票
15 回答
129866 浏览
提问于 2025-04-16 21:46

我有一个大项目,里面有很多模块,每个模块都会往标准输出(也就是屏幕)打印一些东西。随着项目的不断扩大,里面的 print 语句越来越多,导致程序变得非常慢。

所以我现在想在程序运行的时候决定是否要打印任何东西到标准输出。我不能去修改这些模块,因为数量实在太多了。(我知道可以把标准输出重定向到一个文件,但这样做也会很慢。)

我的问题是,怎么把标准输出重定向到“什么都不做”,也就是说,怎么让 print 语句不执行任何操作?

# I want to do something like this.
sys.stdout = None         # this obviously will give an error as Nonetype object does not have any write method.

目前我想到的办法是创建一个类,这个类里面有一个写入方法(这个方法什么都不做),然后把标准输出重定向到这个类的一个实例上。

class DontPrint(object):
    def write(*args): pass

dp = DontPrint()
sys.stdout = dp

在 Python 中有没有现成的机制可以做到这一点?或者有没有比这个更好的方法?

15 个回答

20

如果你使用的是Python 3.4或更高版本,有一个简单又安全的方法可以用标准库来实现:

import contextlib

with contextlib.redirect_stdout(None):
  print("This won't print!")
53

一种很好的方法是创建一个小工具,把你的打印输出包裹起来。然后你只需要在一个with语句中使用它,就可以让所有输出都静音。

Python 2:

import os
import sys
from contextlib import contextmanager

@contextmanager
def silence_stdout():
    old_target = sys.stdout
    try:
        with open(os.devnull, "w") as new_target:
            sys.stdout = new_target
            yield new_target
    finally:
        sys.stdout = old_target

with silence_stdout():
    print("will not print")

print("this will print")

Python 3.4及以上版本:

Python 3.4已经内置了这样的工具,所以你可以简单地使用contextlib,像这样:

import contextlib

with contextlib.redirect_stdout(None):
    print("will not print")

print("this will print")

如果你想要静音的代码直接写入sys.stdout,使用None作为重定向目标是行不通的。你可以使用:

import contextlib
import sys
import os

with contextlib.redirect_stdout(open(os.devnull, 'w')):
    sys.stdout.write("will not print")

sys.stdout.write("this will print")

如果你的代码写入的是stderr而不是stdout,你可以使用contextlib.redirect_stderr来代替redirect_stdout。


运行这段代码时,只会打印第二行输出,而不会打印第一行:

$ python test.py
this will print

这个方法在不同的平台上都能用(Windows、Linux和Mac OSX),而且我觉得比其他答案更简洁。

276

跨平台:

import os
import sys
f = open(os.devnull, 'w')
sys.stdout = f

在Windows上:

f = open('nul', 'w')
sys.stdout = f

在Linux上:

f = open('/dev/null', 'w')
sys.stdout = f

撰写回答