禁止打印调用(python)

dml*_*cht 54 python printing pygame

有没有办法阻止函数调用print


我正在使用该pygame.joystick模块进行我正在进行的游戏.

我创建了一个pygame.joystick.Joystick对象,并在游戏的实际循环中调用其成员函数get_button来检查用户输入.该功能完成了我需要它做的所有事情,但问题是它也会调用print,这会大大减慢游戏速度.

我可以阻止这个电话print吗?

Bri*_*and 64

Python允许您使用任何文件对象覆盖标准输出(stdout).这应该跨平台工作并写入空设备.

import sys, os

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

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


print 'This will print'

blockPrint()
print "This won't"

enablePrint()
print "This will too"
Run Code Online (Sandbox Code Playgroud)

如果您不希望打印一个函数,请blockPrint()在它之前调用,以及enablePrint()何时希望它继续.如果要禁用所有打印,请在文件顶部开始阻止.

  • 这似乎永久阻止了我的打印.enablePrint不会还原它 (14认同)
  • 此解决方案将无法正确恢复打印到Jupyter单元 (3认同)
  • 对于 Jupyter,您可以将“sys”中的原始标准输出保存为“blockPrint”中的“sys._jupyter_stdout = sys.stdout”,并在“enablePrint”中恢复到它 (2认同)

Ale*_*hen 55

基于@FakeRainBrigand解决方案,我建议采用更安全的解决方案:

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.close()
        sys.stdout = self._original_stdout
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

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

print("This will be printed as before")
Run Code Online (Sandbox Code Playgroud)

这样更安全,因为您不能忘记重新启用stdout,这在处理异常时尤其重要.

# This is an example of not-so-good solution
# without 'with' context manager statement.
try:
    disable_prints()
    something_throwing()
    # enable_prints() This wouldn't be enough!
except ValueError:
    handle_error()
finally:
    enable_prints() # That's where it needs to go.
Run Code Online (Sandbox Code Playgroud)

如果您忘记了该finally条款,您的所有print电话都不会打印任何内容.使用该with声明,这是不可能发生的.

使用它是不安全的sys.stdout = None,因为有人可以调用sys.stdout.write()之类的方法

  • 很好的解决方案!我刚刚写了同样的东西然后发现你已经回答了这个问题:D我会添加一些关于为什么这是更好的方法的信息. (3认同)
  • 我在使用此代码时得到`ResourceWarning:unclosed file <_io.TextIOWrapper name ='/ dev/null'mode ='w'coding ='UTF-8'>`,通过设置sys.stdout = None来解决它开(os.devnull, 'W') (2认同)

Fow*_*ler 10

如果您想阻止特定函数发出的打印调用,则使用装饰器有一个更简洁的解决方案。定义以下装饰器:

# decorater used to block function printing to the console
def blockPrinting(func):
    def func_wrapper(*args, **kwargs):
        # block all printing to the console
        sys.stdout = open(os.devnull, 'w')
        # call the method in question
        value = func(*args, **kwargs)
        # enable all printing to the console
        sys.stdout = sys.__stdout__
        # pass the return value of the method back
        return value

    return func_wrapper
Run Code Online (Sandbox Code Playgroud)

然后放在@blockPrinting任何函数之前。例如:

# This will print
def helloWorld():
    print("Hello World!")
helloWorld()

# This will not print
@blockPrinting
def helloWorld2():
    print("Hello World!")
helloWorld2()
Run Code Online (Sandbox Code Playgroud)


For*_*lla 9

正如@Alexander Chzhen所建议的那样,使用上下文管理器比调用一对状态更改函数更安全。

但是,您不需要重新实现上下文管理器-它已经在标准库中。您可以重定向stdout(文件对象print与使用)contextlib.redirect_stdout,也stderrcontextlib.redirect_stderr

import os
import contextlib

with open(os.devnull, "w") as f, contextlib.redirect_stdout(f):
    print("This won't be printed.")
Run Code Online (Sandbox Code Playgroud)

  • 我意识到这是因为我正在使用 Colab。但我让它与 `from IPython.utils import io with io.capture_output() as capture: print("I won't be print.")` 一起使用 (3认同)

Pas*_*lIv 8

如果您使用的是 Jupyter Notebook 或 Colab,请使用以下命令:

from IPython.utils import io

with io.capture_output() as captured:
    print("I will not be printed.")
Run Code Online (Sandbox Code Playgroud)