我需要覆盖一行的标准输出,然后恢复更改

I need to overwrite the stdout for one line, and then revert the change

这是我的:

cfd1 = nltk.ConditionalFreqDist(biglisttagged)
sys.stdout = open(corpus_name+"-pos-word-freq.txt",'w')
cfd1.tabulate()
sys.stdout = sys.__stdout__ #this is supposed to revert the change, but it doesn't.

print("helloword") #I need this to print to stdout

这是因为 tabulate() 会自动写入标准输出,而我需要它来写入文件。

但是,我的问题是这使得 stdout 无法用于程序中的任何其他内容。

在上面的例子中,helloworld 打印不出来,我需要更改什么?

sys_stdout  = sys.stdout
sys.stdout = open(...)
...
sys.stdout = sys_stdout

尝试:

cfd1 = nltk.ConditionalFreqDist(biglisttagged)
stdout_save = sys.stdout
sys.stdout = open(corpus_name+"-pos-word-freq.txt",'w')
cfd1.tabulate()
sys.stdout = stdout_save

print("helloword") #I need this to print to stdout

你运行怎么样?我在 IDLE 上得到了这种行为,其中正常的 stdout 已被替换,并且 __stdout__ 设置为 None.

您可以使用 unittest.mock.patch 为您处理 stdout 的临时重定向。使用 with 语句意味着标准输出将被重置,即使您的代码块中存在异常。

from unittest.mock import patch

cfd1 = nltk.ConditionalFreqDist(biglisttagged)

with open(corpus_name+"-pos-word-freq.txt", "w") as redirect, \
        patch("sys.stdout", new=redirect):
    cfd1.tabulate()

print("helloword")

您可以通过调用将标准输出重定向到文件并将相关值作为参数获取的脚本来解决此问题,然后在不重定向标准输出的情况下继续调用脚本中的流程:

test1.py

    import sys
    cfd1=sys.argv[1]
    sys.stdout = open(corpus_name+"-pos-word-freq.txt",'w')
    cfd1.tabulate()

test2.py

cfd1 = nltk.ConditionalFreqDist(biglisttagged)
execfile("test1.py " + cfd1)
print("helloword")