Python 如何将stdout重定向到文件和'sys.\u stdout\uuuu`?

Python 如何将stdout重定向到文件和'sys.\u stdout\uuuu`?,python,file,stdout,Python,File,Stdout,以下几行将stdout从sys.\uu stdout\uuu更改为文件。这个很好用 import sys sys.stdout = open("stdout.txt", "a") print("test") 但是,我希望输出到文件以及sys.\uu stdout\uu。我需要添加什么以便“测试”将写入两个位置?您可以创建自己的类似文件的对象,其写入方法将数据发送到两个位置,并将其安装为sys.stdout您可以创建自己的类似文件的对象,其写入方法将数据发送到两个位置,并将其安装为sys.std

以下几行将
stdout
sys.\uu stdout\uuu
更改为文件。这个很好用

import sys
sys.stdout = open("stdout.txt", "a")
print("test")

但是,我希望输出到文件以及
sys.\uu stdout\uu
。我需要添加什么以便“测试”将写入两个位置?

您可以创建自己的类似文件的对象,其
写入方法将数据发送到两个位置,并将其安装为
sys.stdout
您可以创建自己的类似文件的对象,其
写入方法将数据发送到两个位置,并将其安装为
sys.stdout
您可以执行类似操作以保持简单,并避免修改
sys.stdout

import sys

my_log = open('log.txt', 'a')

def write_out(data):
    print(data, file=sys.stdout)
    my_log.write(data + '\n')

def write_err(data):
    print(data, file=sys.stderr)
    my_log.write(data + '\n')

def main():
    write_out('test out')
    write_err('test err')

您可以这样做以保持其简单性,并避免修改
sys.stdout

import sys

my_log = open('log.txt', 'a')

def write_out(data):
    print(data, file=sys.stdout)
    my_log.write(data + '\n')

def write_err(data):
    print(data, file=sys.stderr)
    my_log.write(data + '\n')

def main():
    write_out('test out')
    write_err('test err')
可以使用
mock\u write
函数“拦截”对
sys.stdout.write
的调用,该函数将文本写入文件,然后调用原始的
real\u write
函数

导入系统 def mock_write(文本): 打开(“test.txt”、“a”)作为fh: fh.写入(文本) 实写=类型(sys.stdout).write 实写(sys.stdout,text) sys.stdout.write=mock_write 打印(“测试”)
这不太可能,但是如果
sys.stdout
的原始
write
方法发生更改,并且与我们的mock函数不兼容,此解决方案可能会停止与Python的未来版本一起使用

此外,一些函数,例如
subprocess.Popen
,不使用
sys.stdout.write
,而是直接写入文件对象的
fileno
文件描述符。因此模拟写入不会捕获该输出

顺便说一句,这种用另一个函数替换对象现有方法的方法有其局限性:例如,它不适用于神奇方法和
\uuuuuuuuuuuuu
。例如,请参阅以获取进一步阅读。

可以使用
mock\u write
函数“拦截”对
sys.stdout.write
的调用,该函数将文本写入文件,然后调用原始的
real\u write
函数

导入系统 def mock_write(文本): 打开(“test.txt”、“a”)作为fh: fh.写入(文本) 实写=类型(sys.stdout).write 实写(sys.stdout,text) sys.stdout.write=mock_write 打印(“测试”)
这不太可能,但是如果
sys.stdout
的原始
write
方法发生更改,并且与我们的mock函数不兼容,此解决方案可能会停止与Python的未来版本一起使用

此外,一些函数,例如
subprocess.Popen
,不使用
sys.stdout.write
,而是直接写入文件对象的
fileno
文件描述符。因此模拟写入不会捕获该输出


顺便说一句,这种用另一个函数替换对象现有方法的方法有其局限性:例如,它不适用于神奇方法和
\uuuuuuuuuuuuu
。例如,请参阅,以获取进一步的阅读。

如果您在unix系统上,请将stdout管道连接到tee,它将为您解决问题。请小心这样替换标准输出。关键是它是程序用户指定的文件句柄;您正在写入用户请求的文件。如果要写入其他文件,请明确说明:使用
file
参数
print
将输出定向到特定文件。@emmi474是的,在python之外,在命令行上。如果您在unix系统上,将标准输出管道连接到tee,它将为您处理。请小心这样替换标准输出。关键是它是程序用户指定的文件句柄;您正在写入用户请求的文件。如果要写入其他文件,请明确:使用
file
参数
print
将输出定向到命令行上的特定文件。@emmi474是的,在python之外。只有在控制所有输出代码的情况下,这才有效。当然,如果这是一个XY问题,那可能是正确的。@emmi474您可能有
write\u out
write\u err
的变体。这是正确的。如果你想让所有的stdout和stderr在任何情况下都进入你的日志文件,你必须按照@DavisHerring的建议去做。@Wyatt:The:OP可能真的想复制他们自己函数的输出。(他们后来说不是。)只有控制所有的输出代码,这才有效。当然,如果这是一个XY问题,那可能是正确的。@emmi474您可能有
write\u out
write\u err
的变体。这是正确的。如果你想让所有的stdout和stderr在任何情况下都进入你的日志文件,你必须按照@DavisHerring的建议去做。@Wyatt:The:OP可能真的想复制他们自己函数的输出。关于我的编辑:由于在
mock\u write
中不需要
self
(因为它隐藏在
real\u write
中),我们可以使
sys.stdout.write
成为一个普通的函数值属性,而不是一个方法。您还可以通过调用
type(sys.stdout).write(sys.stdout,text)
来避免
real\u write
。它们在查找时成为普通函数,就像普通函数(以及
classmethod
对象)成为方法对象一样。仅供参考:由于以下原因,它在使用魔术方法时失败<代码>\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,我们可以使
sys.stdout.write
成为一个普通的函数值属性,而不是一个方法。您还可以通过调用
type(sys.stdout).write(sy)来避免
real\u write