【问题标题】:sys.__stdout__ works but sys.stdout does notsys.__stdout__ 有效,但 sys.stdout 无效
【发布时间】:2015-06-21 04:07:22
【问题描述】:

有一个名为redirect的函数,它临时将文件source上的操作重定向到文件target。

    def redirect(source, target):
    source.flush()
    fd = source.fileno()
    with os.fdopen(os.dup(fd), source.mode) as source2:
        os.dup2(target.fileno(), fd)
        try:
            yield
        finally:
            source.flush()
            os.dup2(source2.fileno(), fd)

它是从同一个模块调用的

    with tempfile.TemporaryFile() as tmp:
        with redirect(sys.stdout, tmp), nogil:

编译的时候会产生一个AttributeError

AttributeError: StringIO instance has no attribute 'fileno'

在线fd = source.fileno()。

但是当我把sys.stdout换成sys.__stdout__后,就没有这个错误了,测试成功了。

现在我真的很困惑,为什么 __stdout__ 有效但 stdout 无效。

【问题讨论】:

  • 您是在 IDLE 环境中运行程序,还是从另一个 IDE 运行程序?我想如果你从系统命令行运行你的程序,你会得到一个sys.stdout的实际文件。
  • 我正在从终端运行鼻子测试
  • 啊,是的,nosetests 的实现可能将 sys.stdout 替换为 StringIO 对象,以便它可以轻松捕获输出。听起来鼻子测试与您尝试在其下运行的功能不兼容。
  • 看来nosetests为此提供了一个选项。 nosetests -s 工作。

标签: python python-2.7 python-3.x stdout nosetests


【解决方案1】:

正如 Greg 在 cmets 中提到的那样,那是行不通的。我通常做的是临时更改我的标准输出。

@contextmanager
def replace_stdout(replacement):
    _stdout = sys.stdout
    sys.stdout = replacement
    try:
        yield
    finally:
        sys.stdout = _stdout

并使用上下文管理器:

with tempfile.TemporaryFile() as tmp:
    with replace_stdout(sys.stdout, tmp):

这种用法不关心初始标准输出是否有 FD。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-18
    • 2018-09-20
    • 2017-01-08
    • 2012-05-08
    • 2017-03-15
    • 2014-10-30
    • 2011-03-08
    • 2013-11-27
    相关资源
    最近更新 更多