【问题标题】:To prevent a function from printing in the batch console in Python防止函数在 Python 的批处理控制台中打印
【发布时间】:2012-01-16 20:17:31
【问题描述】:

嗯,在我看来,标题已经足够了。 我使用了一些功能,在某些时候会在控制台中打印一些东西。 由于我无法修改它们,所以我想知道在使用这些功能时是否有不打印的解决方案。

非常感谢!

尼哥

【问题讨论】:

  • batch console 是什么?你在说stdout吗?
  • 这是糟糕设计的标志。如果可能,请修复该功能。否则,如果函数使用 Python 的 print,您可以暂时将 sys.stdout 替换为具有空 write 方法的对象。

标签: python printing batch-file


【解决方案1】:

另一种选择是将您的函数包装在装饰器中。

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())

【讨论】:

  • StringIO 导入中有大小写错误 (from io import stringIO)
  • 在silent_fn内,它应该返回fn(*args, **kwargs)
【解决方案2】:

是的,你可以重定向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

只需将my_nasty_function 替换为您的实际功能即可。

编辑:现在应该也可以在 Windows 上工作。

编辑:当有人再次包装你的函数时,使用备份变量重置标准输出会更好

【讨论】:

  • 不需要backup_stdout,可以使用sys.stdout = sys.__stdout__来恢复原状(见here)。另外,最好使用os.devnull,这样它就可以在Windows上运行。
  • @ekhumoro backup_stdout 是一个更好的解决方案,因为调用者可以使用类似的措施来处理您的代码 :) 我的意思是,恢复 stdout 实际上应该 恢复初始值,而不是设置任意值。
  • 如果讨厌的函数抛出错误有什么危害?我想知道如何将其修改为生产就绪。
  • @AlanSE 您可以将my_nasty_function() 包装在try/finally 块中(将stdout (sys.stdout = sys.__stdout__ ) 的重置放在finally 中,您应该可以开始了。
【解决方案3】:

Constantinius 目前接受的答案在大多数情况下都很好用,但在 Jupyter 笔记本中却不行。 以下是如何让它工作(使用可重用功能)...

TLDR~不要使用sys.__stout__,而是备份sys.stdout,稍后再恢复。

在 Jupyter 笔记本中,运行 sys.stdout == sys.__stdout__ 返回 false。这是因为每个单元格都有一个单独的输出流(而不是一个终端实例,即sys.__stdout__)。 因此,对于使用 Jupyter 笔记本的每个人,请务必备份旧的 sys.stdout 路径并在之后恢复它。 这是它的一个函数:

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

将函数及其参数/参数 (args) 传递给 deafen。它会备份旧的 sys.stdout,切换到 os.devnull 并再次返回自身。

对于一个完整的例子,我们可以创建第二个函数 (test_function):

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

现在,如果我们尝试像平常一样使用test_function(也就是没有deafen),我们将在屏幕上打印出一堆输出:

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

但是,当使用deafen 时,我们不会得到新的输出:

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

附带说明,deafen 函数仍返回函数输出。您还可以将deafensys.__stdout__ 一起使用,方法是将sys.stdout = real_stdout 替换为sys.stdout = sys.__stdout__(也可以在使用时删除real_stdout = sys.stdout)。

希望对正在寻找更强大或更灵活的解决方案(可能适用于 Jupyter 笔记本或与多种功能一起使用)的任何人有所帮助!

【讨论】:

    【解决方案4】:

    您可以使用此answer 的修改版本来创建“空”输出上下文来包装函数调用。

    这可以通过在使用时将os.devnull 作为new_stdout 参数传递给stdout_redirected() 上下文管理器函数来完成。

    【讨论】:

      【解决方案5】:

      Constantinius' answer 回答是可以的,但是实际上不需要打开空设备。顺便说一句,如果你想要便携式空设备,有os.devnull

      实际上,你所需要的只是一个类,它会忽略你写给它的任何东西。所以更便携的版本是:

      class NullIO(StringIO):
          def write(self, txt):
             pass
      
      sys.stdout = NullIO()
      
      my_nasty_function()
      
      sys.stdout = sys.__stdout__
      

      .

      【讨论】:

        【解决方案6】:

        Constantinius 的解决方案适用于 *nix,但这应该适用于任何平台:

        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__
        

        【讨论】:

        • 您忘记重定向sys.stdout
        • 所以我做到了。我还没有正确地喝咖啡:\
        • 不是一个好的解决方案,它会在磁盘上创建实际文件,这意味着完全不必要的磁盘 IO 和磁盘空间不足的可能性。
        猜你喜欢
        • 2020-03-17
        • 2020-01-04
        • 1970-01-01
        • 1970-01-01
        • 2016-04-28
        • 2020-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多